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 mountComponent from 'helpers/vue_mount_component_helper';
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', () => {
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(() => {
vm = createComponent({});
createComponent();
});
afterEach(() => {
vm.$destroy();
wrapper.destroy();
});
describe('data', () => {
it('returns default data props', () => {
expect(vm.showAdvanceItems).toBeFalsy();
expect(vm.errorMessage).toBe('');
expect(wrapper.vm.showAdvanceItems).toBeFalsy();
expect(wrapper.vm.errorMessage).toBe('');
});
});
describe('computed', () => {
describe('hasError', () => {
it('returns boolean value representing if node has any errors', () => {
// With altered mock data for Unhealthy status
beforeEach(() => {
const nodeDetails = Object.assign({}, mockNodeDetails, {
health: 'Something went wrong.',
healthy: false,
});
const vmX = createComponent({ nodeDetails });
expect(vmX.errorMessage).toBe('Something went wrong.');
expect(vmX.hasError).toBeTruthy();
vmX.$destroy();
createComponent({ nodeDetails });
});
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
expect(vm.hasError).toBeFalsy();
expect(defaultProps.hasError).toBeFalsy();
});
});
describe('hasVersionMismatch', () => {
it('returns boolean value representing if node has version mismatch', () => {
// With altered mock data for version mismatch
beforeEach(() => {
const nodeDetails = Object.assign({}, mockNodeDetails, {
primaryVersion: '10.3.0-pre',
primaryRevision: 'b93c51850b',
});
const vmX = createComponent({ nodeDetails });
expect(vmX.errorMessage).toBe('GitLab version does not match the primary node version');
expect(vmX.hasVersionMismatch).toBeTruthy();
vmX.$destroy();
createComponent({ nodeDetails });
});
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
expect(vm.hasVersionMismatch).toBeFalsy();
expect(defaultProps.hasVersionMismatch).toBeFalsy();
});
});
});
describe('template', () => {
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 => {
vm.nodeDetails.healthy = false;
vm.errorMessage = 'Foobar';
describe('with error', () => {
beforeEach(() => {
createComponent({
errorMessage: 'Foobar',
nodeDetails: {
...defaultProps.nodeDetails,
healthy: false,
},
});
});
vm.$nextTick(() => {
expect(vm.$el.querySelector('.bg-danger-100 a').getAttribute('href')).toBe('/foo/bar');
done();
it('renders troubleshooting URL within error message section', () => {
expect(
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 eventHub from 'ee/geo_nodes/event_hub';
import mountComponent from 'helpers/vue_mount_component_helper';
import { mockNode, mockNodeDetails } from '../mock_data';
jest.mock('ee/geo_nodes/event_hub');
const createComponent = (node = mockNode) => {
const Component = Vue.extend(geoNodeItemComponent);
describe('GeoNodeItemComponent', () => {
let wrapper;
return mountComponent(Component, {
node,
const defaultProps = {
node: mockNode,
primaryNode: true,
nodeActionsAllowed: true,
nodeEditAllowed: true,
geoTroubleshootingHelpPath: '/foo/bar',
});
};
describe('GeoNodeItemComponent', () => {
let vm;
};
const createComponent = (props = {}) => {
wrapper = shallowMount(geoNodeItemComponent, {
propsData: {
...defaultProps,
...props,
},
});
};
beforeEach(() => {
vm = createComponent();
createComponent();
});
afterEach(() => {
vm.$destroy();
wrapper.destroy();
});
describe('data', () => {
it('returns default data props', () => {
expect(vm.isNodeDetailsLoading).toBe(true);
expect(vm.isNodeDetailsFailed).toBe(false);
expect(vm.nodeHealthStatus).toBe('');
expect(vm.errorMessage).toBe('');
expect(typeof vm.nodeDetails).toBe('object');
expect(wrapper.vm.isNodeDetailsLoading).toBe(true);
expect(wrapper.vm.isNodeDetailsFailed).toBe(false);
expect(wrapper.vm.nodeHealthStatus).toBe('');
expect(wrapper.vm.errorMessage).toBe('');
expect(typeof wrapper.vm.nodeDetails).toBe('object');
});
});
describe('computed', () => {
let vmHttps;
let httpsNode;
beforeEach(() => {
......@@ -50,87 +54,88 @@ describe('GeoNodeItemComponent', () => {
id: mockNodeDetails.id,
url: 'https://127.0.0.1:3001/',
});
vmHttps = createComponent(httpsNode);
});
afterEach(() => {
vmHttps.$destroy();
createComponent({ node: httpsNode });
});
describe('showNodeDetails', () => {
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', () => {
vmHttps.isNodeDetailsLoading = false;
vmHttps.isNodeDetailsFailed = true;
wrapper.vm.isNodeDetailsLoading = false;
wrapper.vm.isNodeDetailsFailed = true;
expect(vmHttps.showNodeDetails).toBeFalsy();
expect(wrapper.vm.showNodeDetails).toBeFalsy();
});
it('returns `true` if Node details loaded', () => {
vmHttps.handleNodeDetails(mockNodeDetails);
vmHttps.isNodeDetailsLoading = false;
vmHttps.isNodeDetailsFailed = false;
wrapper.vm.handleNodeDetails(mockNodeDetails);
wrapper.vm.isNodeDetailsLoading = false;
wrapper.vm.isNodeDetailsFailed = false;
expect(vmHttps.showNodeDetails).toBeTruthy();
expect(wrapper.vm.showNodeDetails).toBeTruthy();
});
});
});
describe('methods', () => {
describe('handleNodeDetails', () => {
it('intializes props based on provided `nodeDetails`', () => {
// With altered mock data with matching ID
const mockNodeSecondary = Object.assign({}, mockNode, {
id: mockNodeDetails.id,
primary: false,
describe('with matching ID', () => {
beforeEach(() => {
const mockNodeSecondary = Object.assign({}, mockNode, {
id: mockNodeDetails.id,
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(vmNodePrimary.isNodeDetailsFailed).toBeFalsy();
expect(vmNodePrimary.errorMessage).toBe('');
expect(vmNodePrimary.nodeDetails).toBe(mockNodeDetails);
expect(vmNodePrimary.nodeHealthStatus).toBe(mockNodeDetails.health);
vmNodePrimary.$destroy();
expect(wrapper.vm.isNodeDetailsLoading).toBeFalsy();
expect(wrapper.vm.isNodeDetailsFailed).toBeFalsy();
expect(wrapper.vm.errorMessage).toBe('');
expect(wrapper.vm.nodeDetails).toBe(mockNodeDetails);
expect(wrapper.vm.nodeHealthStatus).toBe(mockNodeDetails.health);
});
});
// With default mock data without matching ID
vm.handleNodeDetails(mockNodeDetails);
describe('without matching ID', () => {
it('intializes props based on provided `nodeDetails`', () => {
// With default mock data without matching ID
wrapper.vm.handleNodeDetails(mockNodeDetails);
expect(vm.isNodeDetailsLoading).toBeTruthy();
expect(vm.nodeDetails).not.toBe(mockNodeDetails);
expect(vm.nodeHealthStatus).not.toBe(mockNodeDetails.health);
expect(wrapper.vm.isNodeDetailsLoading).toBeTruthy();
expect(wrapper.vm.nodeDetails).not.toBe(mockNodeDetails);
expect(wrapper.vm.nodeHealthStatus).not.toBe(mockNodeDetails.health);
});
});
});
describe('handleMounted', () => {
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', () => {
it('binds `nodeDetailsLoaded` event handler', () => {
const vmX = createComponent();
expect(eventHub.$on).toHaveBeenCalledWith('nodeDetailsLoaded', jasmine.any(Function));
vmX.$destroy();
});
});
describe('beforeDestroy', () => {
it('unbinds `nodeDetailsLoaded` event handler', () => {
const vmX = createComponent();
vmX.$destroy();
wrapper.destroy();
expect(eventHub.$off).toHaveBeenCalledWith('nodeDetailsLoaded', jasmine.any(Function));
});
......@@ -138,18 +143,27 @@ describe('GeoNodeItemComponent', () => {
describe('template', () => {
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 => {
const err = 'Something error message';
vm.isNodeDetailsFailed = true;
vm.errorMessage = err;
Vue.nextTick(() => {
expect(vm.$el.querySelectorAll('p.bg-danger-100').length).not.toBe(0);
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();
describe('with error', () => {
let err;
beforeEach(() => {
err = 'Something error message';
wrapper.setData({ errorMessage: err, isNodeDetailsFailed: true });
});
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