import { mount } from '@vue/test-utils';
import { _CREATE, _EDIT, _VIEW } from '@shell/config/query-params';
import YamlEditor from '@shell/components/YamlEditor';
import { HCI } from '@pkg/harvester/config/labels-annotations';
import HarvesterEditCloudTemplate from '../harvesterhci.io.cloudtemplate.vue';
const OLD_CONFIG = '#cloud-config\npassword: old\n';
const NEW_CONFIG = '#cloud-config\npassword: new\n';
// A cloud-config template as the store gives it, `save` records what would be sent to the API
function cloudTemplate({ isNew = false } = {}) {
const value = {
type: 'configmap',
metadata: {
name: 'tpl',
namespace: 'default',
...(isNew ? {} : { labels: { [HCI.CLOUD_INIT]: 'user' } }),
},
data: isNew ? undefined : { cloudInit: OLD_CONFIG },
$dispatch: jest.fn(),
save: () => Promise.resolve(),
saved: [],
};
jest.spyOn(value, 'save').mockImplementation(() => {
value.saved.push(JSON.parse(JSON.stringify({ metadata: value.metadata, data: value.data })));
return Promise.resolve();
});
return value;
}
// The real shell YamlEditor, with only its CodeMirror editor stubbed, so the events the form listens to are the
// ones the shell emits
function mountForm(mode, value) {
return mount(HarvesterEditCloudTemplate, {
props: { value, mode },
global: {
stubs: {
CruResource: { template: '
' },
Tabbed: { template: '
' },
Tab: { template: '
' },
NameNsDescription: true,
LabeledSelect: true,
CodeMirror: {
name: 'CodeMirror', template: '', emits: ['onInput', 'onReady', 'validationChanged']
},
FileDiff: true,
},
mocks: {
$store: {
getters: {
'prefs/get': jest.fn(),
'type-map/isSpoofed': () => false,
currentStore: () => 'harvester',
'harvester/schemaFor': () => ({ linkFor: () => '/v1/harvester/configmaps' }),
'i18n/t': (key) => key,
},
},
$router: { replace: jest.fn() },
$route: {
name: 'c-cluster-product-resource-id', params: {}, query: {}
},
},
},
});
}
// What a user typing in the editor does: CodeMirror reports the new text to the YamlEditor
async function typeInEditor(wrapper, text) {
wrapper.findComponent(YamlEditor).findComponent({ name: 'CodeMirror' }).vm.$emit('onInput', text);
await wrapper.vm.$nextTick();
}
describe('component: HarvesterEditCloudTemplate', () => {
it('should save the edited cloud config when editing a template', async() => {
const value = cloudTemplate();
const wrapper = mountForm(_EDIT, value);
await typeInEditor(wrapper, NEW_CONFIG);
await wrapper.vm.save(jest.fn());
expect(value.save).toHaveBeenCalledTimes(1);
expect(value.saved[0].data).toStrictEqual({ cloudInit: NEW_CONFIG });
});
it('should keep the template type label when editing a template', async() => {
const value = cloudTemplate();
const wrapper = mountForm(_EDIT, value);
await typeInEditor(wrapper, NEW_CONFIG);
await wrapper.vm.save(jest.fn());
expect(value.saved[0].metadata.labels).toStrictEqual({ [HCI.CLOUD_INIT]: 'user' });
});
it('should save the last text when the cloud config is edited several times', async() => {
const value = cloudTemplate();
const wrapper = mountForm(_EDIT, value);
await typeInEditor(wrapper, '#cloud-config\n');
await typeInEditor(wrapper, NEW_CONFIG);
await wrapper.vm.save(jest.fn());
expect(value.saved[0].data).toStrictEqual({ cloudInit: NEW_CONFIG });
});
it('should save the cloud config unchanged when only saving a template', async() => {
const value = cloudTemplate();
const wrapper = mountForm(_EDIT, value);
await wrapper.vm.save(jest.fn());
expect(value.saved[0].data).toStrictEqual({ cloudInit: OLD_CONFIG });
});
it('should save the cloud config and the template type when creating a template', async() => {
const value = cloudTemplate({ isNew: true });
const wrapper = mountForm(_CREATE, value);
await typeInEditor(wrapper, NEW_CONFIG);
await wrapper.vm.save(jest.fn());
expect(value.save).toHaveBeenCalledWith({ url: '/v1/harvester/configmaps' });
expect(value.saved[0]).toStrictEqual({
metadata: {
name: 'tpl', namespace: 'default', labels: { [HCI.CLOUD_INIT]: 'user' }
},
data: { cloudInit: NEW_CONFIG },
});
});
it('should show the template cloud config in the editor when viewing a template', () => {
const value = cloudTemplate();
const wrapper = mountForm(_VIEW, value);
expect(wrapper.findComponent(YamlEditor).props('value')).toBe(OLD_CONFIG);
expect(value.data).toStrictEqual({ cloudInit: OLD_CONFIG });
});
});