Commit e285fc7f authored by Kushal Pandya's avatar Kushal Pandya

Merge branch '36129_01-update-tests' into 'master'

Refactor some Geo Node tests with vue-test-utils

See merge request gitlab-org/gitlab!27150
parents 17249ad9 047f4c6a
import Vue from 'vue'; import { shallowMount } from '@vue/test-utils';
import Icon from '~/vue_shared/components/icon.vue';
import StackedProgressBar from '~/vue_shared/components/stacked_progress_bar.vue';
import GeoNodeDetailItemComponent from 'ee/geo_nodes/components/geo_node_detail_item.vue';
import GeoNodeSyncSettings from 'ee/geo_nodes/components/geo_node_sync_settings.vue';
import GeoNodeEventStatus from 'ee/geo_nodes/components/geo_node_event_status.vue';
import geoNodeDetailItemComponent from 'ee/geo_nodes/components/geo_node_detail_item.vue';
import { VALUE_TYPE, CUSTOM_TYPE } from 'ee/geo_nodes/constants'; import { VALUE_TYPE, CUSTOM_TYPE } from 'ee/geo_nodes/constants';
import mountComponent from 'helpers/vue_mount_component_helper';
import { rawMockNodeDetails } from '../mock_data'; import { rawMockNodeDetails } from '../mock_data';
const createComponent = config => {
const Component = Vue.extend(geoNodeDetailItemComponent);
const defaultConfig = Object.assign(
{
itemTitle: 'GitLab version',
cssClass: 'node-version',
itemValue: '10.4.0-pre',
successLabel: 'Synced',
failureLabel: 'Failed',
neutralLabel: 'Out of sync',
itemValueType: VALUE_TYPE.PLAIN,
},
config,
);
return mountComponent(Component, defaultConfig);
};
describe('GeoNodeDetailItemComponent', () => { describe('GeoNodeDetailItemComponent', () => {
describe('template', () => { let wrapper;
it('renders container elements correctly', () => {
const vm = createComponent(); const defaultProps = {
itemTitle: 'GitLab version',
expect(vm.$el.classList.contains('node-detail-item')).toBeTruthy(); cssClass: 'node-version',
expect(vm.$el.querySelectorAll('.node-detail-title').length).not.toBe(0); itemValue: '10.4.0-pre',
expect(vm.$el.querySelector('.node-detail-title').innerText.trim()).toBe('GitLab version'); successLabel: 'Synced',
vm.$destroy(); failureLabel: 'Failed',
neutralLabel: 'Out of sync',
itemValueType: VALUE_TYPE.PLAIN,
};
const createComponent = (props = {}) => {
wrapper = shallowMount(GeoNodeDetailItemComponent, {
propsData: {
...defaultProps,
...props,
},
}); });
};
it('renders plain item value', () => { afterEach(() => {
const vm = createComponent(); wrapper.destroy();
});
expect(vm.$el.querySelectorAll('.node-detail-value').length).not.toBe(0); describe('template', () => {
expect(vm.$el.querySelector('.node-detail-value').innerText.trim()).toBe('10.4.0-pre'); beforeEach(() => {
vm.$destroy(); createComponent();
}); });
it('renders item title help info icon and popover with help info', () => { it('renders container elements correctly', () => {
const helpInfo = { expect(wrapper.vm.$el.classList.contains('node-detail-item')).toBeTruthy();
title: 'Foo title tooltip', expect(wrapper.vm.$el.querySelectorAll('.node-detail-title').length).not.toBe(0);
url: 'https://docs.gitlab.com', expect(wrapper.vm.$el.querySelector('.node-detail-title').innerText.trim()).toBe(
urlText: 'Help', 'GitLab version',
}; );
const vm = createComponent({ helpInfo });
const helpTextIconEl = vm.$el.querySelector('.node-detail-help-text');
expect(helpTextIconEl).not.toBeNull();
expect(helpTextIconEl.querySelector('use').getAttribute('xlink:href')).toContain('question');
vm.$destroy();
}); });
it('renders graph item value', () => { it('renders plain item value', () => {
const vm = createComponent({ expect(wrapper.vm.$el.querySelectorAll('.node-detail-value').length).not.toBe(0);
itemValueType: VALUE_TYPE.GRAPH, expect(wrapper.vm.$el.querySelector('.node-detail-value').innerText.trim()).toBe(
itemValue: { successCount: 5, failureCount: 3, totalCount: 10 }, '10.4.0-pre',
);
});
describe('with help info', () => {
beforeEach(() => {
createComponent({
helpInfo: {
title: 'Foo title tooltip',
url: 'https://docs.gitlab.com',
urlText: 'Help',
},
});
}); });
expect(vm.$el.querySelectorAll('.stacked-progress-bar').length).not.toBe(0); it('renders item title help info icon', () => {
vm.$destroy(); const helpTextIconEl = wrapper.find(Icon);
expect(helpTextIconEl.exists()).toBeTruthy();
expect(helpTextIconEl.attributes('name')).toBe('question');
});
}); });
it('renders stale information status icon when `itemValueStale` prop is true', () => { describe('when graph item value', () => {
const itemValueStaleTooltip = 'Data is out of date from 8 hours ago'; beforeEach(() => {
const vm = createComponent({ createComponent({
itemValueType: VALUE_TYPE.GRAPH, itemValueType: VALUE_TYPE.GRAPH,
itemValue: { successCount: 5, failureCount: 3, totalCount: 10 }, itemValue: { successCount: 5, failureCount: 3, totalCount: 10 },
itemValueStale: true, });
itemValueStaleTooltip,
}); });
const iconEl = vm.$el.querySelector('.text-warning-500'); it('renders progress bar', () => {
expect(wrapper.find(StackedProgressBar).exists()).toBeTruthy();
});
expect(iconEl).not.toBeNull(); describe('with itemValueStale prop', () => {
expect(iconEl.dataset.originalTitle).toBe(itemValueStaleTooltip); const itemValueStaleTooltip = 'Data is out of date from 8 hours ago';
expect(iconEl.querySelector('use').getAttribute('xlink:href')).toContain('time-out');
vm.$destroy(); beforeEach(() => {
createComponent({
itemValueType: VALUE_TYPE.GRAPH,
itemValue: { successCount: 5, failureCount: 3, totalCount: 10 },
itemValueStale: true,
itemValueStaleTooltip,
});
});
it('renders stale information icon', () => {
const iconEl = wrapper.find('.text-warning-500');
expect(iconEl).not.toBeNull();
expect(iconEl.attributes('data-original-title')).toBe(itemValueStaleTooltip);
expect(iconEl.attributes('name')).toBe('time-out');
});
});
}); });
it('renders sync settings item value', () => { describe('when custom type is sync', () => {
const vm = createComponent({ beforeEach(() => {
itemValueType: VALUE_TYPE.CUSTOM, createComponent({
customType: CUSTOM_TYPE.SYNC, itemValueType: VALUE_TYPE.CUSTOM,
itemValue: { customType: CUSTOM_TYPE.SYNC,
namespaces: rawMockNodeDetails.namespaces, itemValue: {
lastEvent: { namespaces: rawMockNodeDetails.namespaces,
id: rawMockNodeDetails.last_event_id, lastEvent: {
timeStamp: rawMockNodeDetails.last_event_timestamp, id: rawMockNodeDetails.last_event_id,
timeStamp: rawMockNodeDetails.last_event_timestamp,
},
cursorLastEvent: {
id: rawMockNodeDetails.cursor_last_event_id,
timeStamp: rawMockNodeDetails.cursor_last_event_timestamp,
},
}, },
cursorLastEvent: { });
id: rawMockNodeDetails.cursor_last_event_id,
timeStamp: rawMockNodeDetails.cursor_last_event_timestamp,
},
},
}); });
expect(vm.$el.querySelectorAll('.node-sync-settings').length).not.toBe(0); it('renders sync settings item value', () => {
vm.$destroy(); expect(wrapper.find(GeoNodeSyncSettings).exists()).toBeTruthy();
});
}); });
it('renders event status item value', () => { describe('when custom type is event', () => {
const vm = createComponent({ beforeEach(() => {
itemValueType: VALUE_TYPE.CUSTOM, createComponent({
customType: CUSTOM_TYPE.EVENT, itemValueType: VALUE_TYPE.CUSTOM,
itemValue: { customType: CUSTOM_TYPE.EVENT,
eventId: rawMockNodeDetails.last_event_id, itemValue: {
eventTimeStamp: rawMockNodeDetails.last_event_timestamp, eventId: rawMockNodeDetails.last_event_id,
}, eventTimeStamp: rawMockNodeDetails.last_event_timestamp,
},
});
}); });
expect(vm.$el.querySelectorAll('.event-status-timestamp').length).not.toBe(0); it('renders event status item value', () => {
vm.$destroy(); expect(wrapper.find(GeoNodeEventStatus).exists()).toBeTruthy();
});
}); });
it('does not render if featureDisabled is true', () => { describe('when featureDisabled is true', () => {
const vm = createComponent({ beforeEach(() => {
featureDisabled: true, createComponent({
featureDisabled: true,
});
}); });
expect(vm.$el.innerHTML).toBeUndefined(); it('does not render', () => {
vm.$destroy(); expect(wrapper.vm.$el.innerHTML).toBeUndefined();
});
}); });
}); });
}); });
import Vue from 'vue'; import { shallowMount } from '@vue/test-utils';
import NodeDetailsSectionSyncComponent from 'ee/geo_nodes/components/node_detail_sections/node_details_section_sync.vue'; import NodeDetailsSectionSyncComponent from 'ee/geo_nodes/components/node_detail_sections/node_details_section_sync.vue';
import mountComponent from 'helpers/vue_mount_component_helper'; import SectionRevealButton from 'ee/geo_nodes/components/node_detail_sections/section_reveal_button.vue';
import { mockNodeDetails } from '../../mock_data';
const createComponent = (nodeDetails = Object.assign({}, mockNodeDetails)) => { import { mockNode, mockNodeDetails } from '../../mock_data';
const Component = Vue.extend(NodeDetailsSectionSyncComponent);
return mountComponent(Component, {
nodeDetails,
});
};
describe('NodeDetailsSectionSync', () => { describe('NodeDetailsSectionSync', () => {
let vm; let wrapper;
const propsData = {
node: mockNode,
nodeDetails: mockNodeDetails,
};
const createComponent = () => {
wrapper = shallowMount(NodeDetailsSectionSyncComponent, {
stubs: {
geoNodeSyncProgress: true,
},
propsData,
});
};
beforeEach(() => { beforeEach(() => {
gon.features = gon.features || {}; gon.features = gon.features || {};
vm = createComponent(); createComponent();
}); });
afterEach(() => { afterEach(() => {
vm.$destroy(); wrapper.destroy();
}); });
describe('data', () => { describe('data', () => {
it('returns default data props', () => { it('returns default data props', () => {
expect(vm.showSectionItems).toBe(false); expect(wrapper.vm.showSectionItems).toBe(false);
expect(Array.isArray(vm.nodeDetailItems)).toBe(true); expect(Array.isArray(wrapper.vm.nodeDetailItems)).toBe(true);
expect(vm.nodeDetailItems.length).toBeGreaterThan(0); expect(wrapper.vm.nodeDetailItems.length).toBeGreaterThan(0);
}); });
}); });
describe('methods', () => { describe('methods', () => {
describe('syncSettings', () => { describe('syncSettings', () => {
it('returns sync settings object', done => { it('returns sync settings object', () => {
vm.nodeDetails.syncStatusUnavailable = true; wrapper.vm.nodeDetails.syncStatusUnavailable = true;
Vue.nextTick() return wrapper.vm.$nextTick(() => {
.then(() => { const syncSettings = wrapper.vm.syncSettings();
const syncSettings = vm.syncSettings(); expect(syncSettings.syncStatusUnavailable).toBe(true);
expect(syncSettings.namespaces).toBe(mockNodeDetails.namespaces);
expect(syncSettings.syncStatusUnavailable).toBe(true); expect(syncSettings.lastEvent).toBe(mockNodeDetails.lastEvent);
expect(syncSettings.namespaces).toBe(mockNodeDetails.namespaces); expect(syncSettings.cursorLastEvent).toBe(mockNodeDetails.cursorLastEvent);
expect(syncSettings.lastEvent).toBe(mockNodeDetails.lastEvent); });
expect(syncSettings.cursorLastEvent).toBe(mockNodeDetails.cursorLastEvent);
})
.then(done)
.catch(done.fail);
}); });
}); });
describe('dbReplicationLag', () => { describe('dbReplicationLag', () => {
it('returns DB replication lag time duration', () => { it('returns DB replication lag time duration', () => {
expect(vm.dbReplicationLag()).toBe('0m'); expect(wrapper.vm.dbReplicationLag()).toBe('0m');
}); });
it('returns `Unknown` when `dbReplicationLag` is null', done => { it('returns `Unknown` when `dbReplicationLag` is null', () => {
vm.nodeDetails.dbReplicationLag = null; wrapper.vm.nodeDetails.dbReplicationLag = null;
Vue.nextTick() return wrapper.vm.$nextTick(() => {
.then(() => { expect(wrapper.vm.dbReplicationLag()).toBe('Unknown');
expect(vm.dbReplicationLag()).toBe('Unknown'); });
})
.then(done)
.catch(done.fail);
}); });
}); });
describe('lastEventStatus', () => { describe('lastEventStatus', () => {
it('returns event status object', () => { it('returns event status object', () => {
expect(vm.lastEventStatus().eventId).toBe(mockNodeDetails.lastEvent.id); expect(wrapper.vm.lastEventStatus().eventId).toBe(mockNodeDetails.lastEvent.id);
expect(vm.lastEventStatus().eventTimeStamp).toBe(mockNodeDetails.lastEvent.timeStamp); expect(wrapper.vm.lastEventStatus().eventTimeStamp).toBe(
mockNodeDetails.lastEvent.timeStamp,
);
}); });
}); });
describe('cursorLastEventStatus', () => { describe('cursorLastEventStatus', () => {
it('returns event status object', () => { it('returns event status object', () => {
expect(vm.cursorLastEventStatus().eventId).toBe(mockNodeDetails.cursorLastEvent.id); expect(wrapper.vm.cursorLastEventStatus().eventId).toBe(mockNodeDetails.cursorLastEvent.id);
expect(vm.cursorLastEventStatus().eventTimeStamp).toBe( expect(wrapper.vm.cursorLastEventStatus().eventTimeStamp).toBe(
mockNodeDetails.cursorLastEvent.timeStamp, mockNodeDetails.cursorLastEvent.timeStamp,
); );
}); });
...@@ -85,19 +87,18 @@ describe('NodeDetailsSectionSync', () => { ...@@ -85,19 +87,18 @@ describe('NodeDetailsSectionSync', () => {
describe('template', () => { describe('template', () => {
it('renders component container element', () => { it('renders component container element', () => {
expect(vm.$el.classList.contains('sync-section')).toBe(true); expect(wrapper.vm.$el.classList.contains('sync-section')).toBe(true);
}); });
it('renders show section button element', () => { it('renders show section button element', () => {
expect(vm.$el.querySelector('.btn-link')).not.toBeNull(); expect(wrapper.find(SectionRevealButton).exists()).toBeTruthy();
expect(vm.$el.querySelector('.btn-link > span').innerText.trim()).toBe('Sync information'); expect(wrapper.find(SectionRevealButton).attributes('buttontitle')).toBe('Sync information');
}); });
it('renders section items container element', done => { it('renders section items container element', () => {
vm.showSectionItems = true; wrapper.vm.showSectionItems = true;
Vue.nextTick(() => { return wrapper.vm.$nextTick(() => {
expect(vm.$el.querySelector('.section-items-container')).not.toBeNull(); expect(wrapper.vm.$el.querySelector('.section-items-container')).not.toBeNull();
done();
}); });
}); });
}); });
......
import Vue from 'vue'; import { shallowMount } from '@vue/test-utils';
import NodeDetailsSectionVerificationComponent from 'ee/geo_nodes/components/node_detail_sections/node_details_section_verification.vue'; import NodeDetailsSectionVerificationComponent from 'ee/geo_nodes/components/node_detail_sections/node_details_section_verification.vue';
import mountComponent from 'helpers/vue_mount_component_helper'; import SectionRevealButton from 'ee/geo_nodes/components/node_detail_sections/section_reveal_button.vue';
import { mockNodeDetails } from '../../mock_data'; import { mockNodeDetails } from '../../mock_data';
const createComponent = ({ nodeDetails = mockNodeDetails, nodeTypePrimary = false }) => { describe('NodeDetailsSectionVerification', () => {
const Component = Vue.extend(NodeDetailsSectionVerificationComponent); let wrapper;
return mountComponent(Component, { const propsData = {
nodeDetails, nodeDetails: mockNodeDetails,
nodeTypePrimary, nodeTypePrimary: false,
}); };
};
describe('NodeDetailsSectionVerification', () => { const createComponent = () => {
let vm; wrapper = shallowMount(NodeDetailsSectionVerificationComponent, {
propsData,
});
};
beforeEach(() => { beforeEach(() => {
vm = createComponent({}); createComponent();
}); });
afterEach(() => { afterEach(() => {
vm.$destroy(); wrapper.destroy();
}); });
describe('data', () => { describe('data', () => {
it('returns default data props', () => { it('returns default data props', () => {
expect(vm.showSectionItems).toBe(false); expect(wrapper.vm.showSectionItems).toBe(false);
expect(Array.isArray(vm.primaryNodeDetailItems)).toBe(true); expect(Array.isArray(wrapper.vm.primaryNodeDetailItems)).toBe(true);
expect(Array.isArray(vm.secondaryNodeDetailItems)).toBe(true); expect(Array.isArray(wrapper.vm.secondaryNodeDetailItems)).toBe(true);
expect(vm.primaryNodeDetailItems.length).toBeGreaterThan(0); expect(wrapper.vm.primaryNodeDetailItems.length).toBeGreaterThan(0);
expect(vm.secondaryNodeDetailItems.length).toBeGreaterThan(0); expect(wrapper.vm.secondaryNodeDetailItems.length).toBeGreaterThan(0);
}); });
}); });
...@@ -48,7 +51,7 @@ describe('NodeDetailsSectionVerification', () => { ...@@ -48,7 +51,7 @@ describe('NodeDetailsSectionVerification', () => {
]; ];
it('returns array containing items to show under primary node', () => { it('returns array containing items to show under primary node', () => {
const actualPrimaryItems = vm.getPrimaryNodeDetailItems(); const actualPrimaryItems = wrapper.vm.getPrimaryNodeDetailItems();
primaryItems.forEach((item, index) => { primaryItems.forEach((item, index) => {
expect(actualPrimaryItems[index].itemTitle).toBe(item.title); expect(actualPrimaryItems[index].itemTitle).toBe(item.title);
expect(actualPrimaryItems[index].itemValue).toBe(mockNodeDetails[item.valueProp]); expect(actualPrimaryItems[index].itemValue).toBe(mockNodeDetails[item.valueProp]);
...@@ -69,7 +72,7 @@ describe('NodeDetailsSectionVerification', () => { ...@@ -69,7 +72,7 @@ describe('NodeDetailsSectionVerification', () => {
]; ];
it('returns array containing items to show under secondary node', () => { it('returns array containing items to show under secondary node', () => {
const actualSecondaryItems = vm.getSecondaryNodeDetailItems(); const actualSecondaryItems = wrapper.vm.getSecondaryNodeDetailItems();
secondaryItems.forEach((item, index) => { secondaryItems.forEach((item, index) => {
expect(actualSecondaryItems[index].itemTitle).toBe(item.title); expect(actualSecondaryItems[index].itemTitle).toBe(item.title);
expect(actualSecondaryItems[index].itemValue).toBe(mockNodeDetails[item.valueProp]); expect(actualSecondaryItems[index].itemValue).toBe(mockNodeDetails[item.valueProp]);
...@@ -80,21 +83,20 @@ describe('NodeDetailsSectionVerification', () => { ...@@ -80,21 +83,20 @@ describe('NodeDetailsSectionVerification', () => {
describe('template', () => { describe('template', () => {
it('renders component container element', () => { it('renders component container element', () => {
expect(vm.$el.classList.contains('verification-section')).toBe(true); expect(wrapper.vm.$el.classList.contains('verification-section')).toBe(true);
}); });
it('renders show section button element', () => { it('renders show section button element', () => {
expect(vm.$el.querySelector('.btn-link')).not.toBeNull(); expect(wrapper.find(SectionRevealButton).exists()).toBeTruthy();
expect(vm.$el.querySelector('.btn-link > span').innerText.trim()).toBe( expect(wrapper.find(SectionRevealButton).attributes('buttontitle')).toBe(
'Verification information', 'Verification information',
); );
}); });
it('renders section items container element', done => { it('renders section items container element', () => {
vm.showSectionItems = true; wrapper.vm.showSectionItems = true;
Vue.nextTick(() => { return wrapper.vm.$nextTick(() => {
expect(vm.$el.querySelector('.section-items-container')).not.toBeNull(); expect(wrapper.vm.$el.querySelector('.section-items-container')).not.toBeNull();
done();
}); });
}); });
}); });
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment