Commit 3a16d489 authored by Zack Cuddy's avatar Zack Cuddy

Refactor additional Geo Node tests

This MR splits off from:
https://gitlab.com/gitlab-org/gitlab/-/merge_requests/27624

In the above MR, GlPopover is implemented.
There are some problems when fully
mounting it in a spec.

Using shallowMount and stubbing it fixes the problem,
however, the affected tests were written without
vue-test-utils and thus cannot shallowMount.

This MR simply rewrites the impacted tests with
vue-test-utils and shallowMounts the components.
parent d1ed6c02
import Vue from 'vue'; import { shallowMount } from '@vue/test-utils';
import { GlLink } from '@gitlab/ui';
import geoNodeDetailsComponent from 'ee/geo_nodes/components/geo_node_details.vue'; import geoNodeDetailsComponent from 'ee/geo_nodes/components/geo_node_details.vue';
import mountComponent from 'helpers/vue_mount_component_helper';
import { mockNode, mockNodeDetails } from '../mock_data'; import { mockNode, mockNodeDetails } from '../mock_data';
const createComponent = ({
node = mockNode,
nodeDetails = mockNodeDetails,
nodeActionsAllowed = true,
nodeEditAllowed = true,
}) => {
const Component = Vue.extend(geoNodeDetailsComponent);
return mountComponent(Component, {
node,
nodeDetails,
nodeActionsAllowed,
nodeEditAllowed,
geoTroubleshootingHelpPath: '/foo/bar',
});
};
describe('GeoNodeDetailsComponent', () => { describe('GeoNodeDetailsComponent', () => {
let vm; let wrapper;
const defaultProps = {
node: mockNode,
nodeDetails: mockNodeDetails,
nodeActionsAllowed: true,
nodeEditAllowed: true,
geoTroubleshootingHelpPath: '/foo/bar',
};
const createComponent = (props = {}) => {
wrapper = shallowMount(geoNodeDetailsComponent, {
propsData: {
...defaultProps,
...props,
},
});
};
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.showAdvanceItems).toBeFalsy(); expect(wrapper.vm.showAdvanceItems).toBeFalsy();
expect(vm.errorMessage).toBe(''); expect(wrapper.vm.errorMessage).toBe('');
}); });
}); });
describe('computed', () => { describe('computed', () => {
describe('hasError', () => { describe('hasError', () => {
it('returns boolean value representing if node has any errors', () => { beforeEach(() => {
// With altered mock data for Unhealthy status
const nodeDetails = Object.assign({}, mockNodeDetails, { const nodeDetails = Object.assign({}, mockNodeDetails, {
health: 'Something went wrong.', health: 'Something went wrong.',
healthy: false, healthy: false,
}); });
const vmX = createComponent({ nodeDetails });
expect(vmX.errorMessage).toBe('Something went wrong.'); createComponent({ nodeDetails });
expect(vmX.hasError).toBeTruthy(); });
vmX.$destroy();
it('returns boolean value representing if node has any errors', () => {
// With altered mock data for Unhealthy status
expect(wrapper.vm.errorMessage).toBe('Something went wrong.');
expect(wrapper.vm.hasError).toBeTruthy();
// With default mock data // With default mock data
expect(vm.hasError).toBeFalsy(); expect(defaultProps.hasError).toBeFalsy();
}); });
}); });
describe('hasVersionMismatch', () => { describe('hasVersionMismatch', () => {
it('returns boolean value representing if node has version mismatch', () => { beforeEach(() => {
// With altered mock data for version mismatch
const nodeDetails = Object.assign({}, mockNodeDetails, { const nodeDetails = Object.assign({}, mockNodeDetails, {
primaryVersion: '10.3.0-pre', primaryVersion: '10.3.0-pre',
primaryRevision: 'b93c51850b', primaryRevision: 'b93c51850b',
}); });
const vmX = createComponent({ nodeDetails });
expect(vmX.errorMessage).toBe('GitLab version does not match the primary node version'); createComponent({ nodeDetails });
expect(vmX.hasVersionMismatch).toBeTruthy(); });
vmX.$destroy();
it('returns boolean value representing if node has version mismatch', () => {
// With altered mock data for version mismatch
expect(wrapper.vm.errorMessage).toBe(
'GitLab version does not match the primary node version',
);
expect(wrapper.vm.hasVersionMismatch).toBeTruthy();
// With default mock data // With default mock data
expect(vm.hasVersionMismatch).toBeFalsy(); expect(defaultProps.hasVersionMismatch).toBeFalsy();
}); });
}); });
}); });
describe('template', () => { describe('template', () => {
it('renders container elements correctly', () => { it('renders container elements correctly', () => {
expect(vm.$el.classList.contains('card-body')).toBe(true); expect(wrapper.vm.$el.classList.contains('card-body')).toBe(true);
}); });
it('renders troubleshooting URL within error message section', done => { describe('with error', () => {
vm.nodeDetails.healthy = false; beforeEach(() => {
vm.errorMessage = 'Foobar'; createComponent({
errorMessage: 'Foobar',
nodeDetails: {
...defaultProps.nodeDetails,
healthy: false,
},
});
});
vm.$nextTick(() => { it('renders troubleshooting URL within error message section', () => {
expect(vm.$el.querySelector('.bg-danger-100 a').getAttribute('href')).toBe('/foo/bar'); expect(
done(); wrapper
.find('.bg-danger-100')
.find(GlLink)
.attributes('href'),
).toBe('/foo/bar');
}); });
}); });
}); });
......
import Vue from 'vue'; import { shallowMount } from '@vue/test-utils';
import { GlLink } from '@gitlab/ui';
import geoNodeItemComponent from 'ee/geo_nodes/components/geo_node_item.vue'; import geoNodeItemComponent from 'ee/geo_nodes/components/geo_node_item.vue';
import eventHub from 'ee/geo_nodes/event_hub'; import eventHub from 'ee/geo_nodes/event_hub';
import mountComponent from 'helpers/vue_mount_component_helper';
import { mockNode, mockNodeDetails } from '../mock_data'; import { mockNode, mockNodeDetails } from '../mock_data';
jest.mock('ee/geo_nodes/event_hub'); jest.mock('ee/geo_nodes/event_hub');
const createComponent = (node = mockNode) => { describe('GeoNodeItemComponent', () => {
const Component = Vue.extend(geoNodeItemComponent); let wrapper;
return mountComponent(Component, { const defaultProps = {
node, node: mockNode,
primaryNode: true, primaryNode: true,
nodeActionsAllowed: true, nodeActionsAllowed: true,
nodeEditAllowed: true, nodeEditAllowed: true,
geoTroubleshootingHelpPath: '/foo/bar', geoTroubleshootingHelpPath: '/foo/bar',
}); };
};
const createComponent = (props = {}) => {
describe('GeoNodeItemComponent', () => { wrapper = shallowMount(geoNodeItemComponent, {
let vm; propsData: {
...defaultProps,
...props,
},
});
};
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.isNodeDetailsLoading).toBe(true); expect(wrapper.vm.isNodeDetailsLoading).toBe(true);
expect(vm.isNodeDetailsFailed).toBe(false); expect(wrapper.vm.isNodeDetailsFailed).toBe(false);
expect(vm.nodeHealthStatus).toBe(''); expect(wrapper.vm.nodeHealthStatus).toBe('');
expect(vm.errorMessage).toBe(''); expect(wrapper.vm.errorMessage).toBe('');
expect(typeof vm.nodeDetails).toBe('object'); expect(typeof wrapper.vm.nodeDetails).toBe('object');
}); });
}); });
describe('computed', () => { describe('computed', () => {
let vmHttps;
let httpsNode; let httpsNode;
beforeEach(() => { beforeEach(() => {
...@@ -50,87 +54,88 @@ describe('GeoNodeItemComponent', () => { ...@@ -50,87 +54,88 @@ describe('GeoNodeItemComponent', () => {
id: mockNodeDetails.id, id: mockNodeDetails.id,
url: 'https://127.0.0.1:3001/', url: 'https://127.0.0.1:3001/',
}); });
vmHttps = createComponent(httpsNode);
});
afterEach(() => { createComponent({ node: httpsNode });
vmHttps.$destroy();
}); });
describe('showNodeDetails', () => { describe('showNodeDetails', () => {
it('returns `false` if Node details are still loading', () => { it('returns `false` if Node details are still loading', () => {
vmHttps.isNodeDetailsLoading = true; wrapper.vm.isNodeDetailsLoading = true;
expect(vmHttps.showNodeDetails).toBeFalsy(); expect(wrapper.vm.showNodeDetails).toBeFalsy();
}); });
it('returns `false` if Node details failed to load', () => { it('returns `false` if Node details failed to load', () => {
vmHttps.isNodeDetailsLoading = false; wrapper.vm.isNodeDetailsLoading = false;
vmHttps.isNodeDetailsFailed = true; wrapper.vm.isNodeDetailsFailed = true;
expect(vmHttps.showNodeDetails).toBeFalsy(); expect(wrapper.vm.showNodeDetails).toBeFalsy();
}); });
it('returns `true` if Node details loaded', () => { it('returns `true` if Node details loaded', () => {
vmHttps.handleNodeDetails(mockNodeDetails); wrapper.vm.handleNodeDetails(mockNodeDetails);
vmHttps.isNodeDetailsLoading = false; wrapper.vm.isNodeDetailsLoading = false;
vmHttps.isNodeDetailsFailed = false; wrapper.vm.isNodeDetailsFailed = false;
expect(vmHttps.showNodeDetails).toBeTruthy(); expect(wrapper.vm.showNodeDetails).toBeTruthy();
}); });
}); });
}); });
describe('methods', () => { describe('methods', () => {
describe('handleNodeDetails', () => { describe('handleNodeDetails', () => {
it('intializes props based on provided `nodeDetails`', () => { describe('with matching ID', () => {
// With altered mock data with matching ID beforeEach(() => {
const mockNodeSecondary = Object.assign({}, mockNode, { const mockNodeSecondary = Object.assign({}, mockNode, {
id: mockNodeDetails.id, id: mockNodeDetails.id,
primary: false, primary: false,
});
createComponent({ node: mockNodeSecondary });
}); });
const vmNodePrimary = createComponent(mockNodeSecondary);
vmNodePrimary.handleNodeDetails(mockNodeDetails); it('intializes props based on provided `nodeDetails`', () => {
// With altered mock data with matching ID
wrapper.vm.handleNodeDetails(mockNodeDetails);
expect(vmNodePrimary.isNodeDetailsLoading).toBeFalsy(); expect(wrapper.vm.isNodeDetailsLoading).toBeFalsy();
expect(vmNodePrimary.isNodeDetailsFailed).toBeFalsy(); expect(wrapper.vm.isNodeDetailsFailed).toBeFalsy();
expect(vmNodePrimary.errorMessage).toBe(''); expect(wrapper.vm.errorMessage).toBe('');
expect(vmNodePrimary.nodeDetails).toBe(mockNodeDetails); expect(wrapper.vm.nodeDetails).toBe(mockNodeDetails);
expect(vmNodePrimary.nodeHealthStatus).toBe(mockNodeDetails.health); expect(wrapper.vm.nodeHealthStatus).toBe(mockNodeDetails.health);
vmNodePrimary.$destroy(); });
});
// With default mock data without matching ID describe('without matching ID', () => {
vm.handleNodeDetails(mockNodeDetails); it('intializes props based on provided `nodeDetails`', () => {
// With default mock data without matching ID
wrapper.vm.handleNodeDetails(mockNodeDetails);
expect(vm.isNodeDetailsLoading).toBeTruthy(); expect(wrapper.vm.isNodeDetailsLoading).toBeTruthy();
expect(vm.nodeDetails).not.toBe(mockNodeDetails); expect(wrapper.vm.nodeDetails).not.toBe(mockNodeDetails);
expect(vm.nodeHealthStatus).not.toBe(mockNodeDetails.health); expect(wrapper.vm.nodeHealthStatus).not.toBe(mockNodeDetails.health);
});
}); });
}); });
describe('handleMounted', () => { describe('handleMounted', () => {
it('emits `pollNodeDetails` event and passes node ID', () => { it('emits `pollNodeDetails` event and passes node ID', () => {
vm.handleMounted(); wrapper.vm.handleMounted();
expect(eventHub.$emit).toHaveBeenCalledWith('pollNodeDetails', vm.node); expect(eventHub.$emit).toHaveBeenCalledWith('pollNodeDetails', wrapper.vm.node);
}); });
}); });
}); });
describe('created', () => { describe('created', () => {
it('binds `nodeDetailsLoaded` event handler', () => { it('binds `nodeDetailsLoaded` event handler', () => {
const vmX = createComponent();
expect(eventHub.$on).toHaveBeenCalledWith('nodeDetailsLoaded', jasmine.any(Function)); expect(eventHub.$on).toHaveBeenCalledWith('nodeDetailsLoaded', jasmine.any(Function));
vmX.$destroy();
}); });
}); });
describe('beforeDestroy', () => { describe('beforeDestroy', () => {
it('unbinds `nodeDetailsLoaded` event handler', () => { it('unbinds `nodeDetailsLoaded` event handler', () => {
const vmX = createComponent(); wrapper.destroy();
vmX.$destroy();
expect(eventHub.$off).toHaveBeenCalledWith('nodeDetailsLoaded', jasmine.any(Function)); expect(eventHub.$off).toHaveBeenCalledWith('nodeDetailsLoaded', jasmine.any(Function));
}); });
...@@ -138,18 +143,27 @@ describe('GeoNodeItemComponent', () => { ...@@ -138,18 +143,27 @@ describe('GeoNodeItemComponent', () => {
describe('template', () => { describe('template', () => {
it('renders container element', () => { it('renders container element', () => {
expect(vm.$el.classList.contains('card', 'geo-node-item')).toBe(true); expect(wrapper.vm.$el.classList.contains('card', 'geo-node-item')).toBe(true);
}); });
it('renders node error message', done => { describe('with error', () => {
const err = 'Something error message'; let err;
vm.isNodeDetailsFailed = true;
vm.errorMessage = err; beforeEach(() => {
Vue.nextTick(() => { err = 'Something error message';
expect(vm.$el.querySelectorAll('p.bg-danger-100').length).not.toBe(0); wrapper.setData({ errorMessage: err, isNodeDetailsFailed: true });
expect(vm.$el.querySelector('p.bg-danger-100').innerText.trim()).toContain(err); });
expect(vm.$el.querySelector('p.bg-danger-100 a').getAttribute('href')).toBe('/foo/bar');
done(); it('renders node error message', () => {
const findErrorMessage = () => wrapper.find('.bg-danger-100');
expect(findErrorMessage().exists()).toBeTruthy();
expect(findErrorMessage().text()).toContain(err);
expect(
findErrorMessage()
.find(GlLink)
.attributes('href'),
).toBe('/foo/bar');
}); });
}); });
}); });
......
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