Commit 3f98bc16 authored by Natalia Tepluhina's avatar Natalia Tepluhina

Merge branch 'vs-migrate-sidebar-to-jest' into 'master'

Migrate ee/spec/javascripts/sidebar/ to Jest

Closes #194307

See merge request gitlab-org/gitlab!26959
parents ee1d9370 3a2cfa31
......@@ -6,7 +6,7 @@ import {
mockSidebarStore,
mockEpic1,
mockIssue,
} from '../../vue_shared/components/sidebar/mock_data';
} from 'ee_jest/vue_shared/components/sidebar/mock_data';
describe('SidebarItemEpicsSelect', () => {
let wrapper;
......@@ -32,50 +32,46 @@ describe('SidebarItemEpicsSelect', () => {
describe('methods', () => {
describe('getInitialEpicLoading', () => {
it('should return `false` when `initialEpic` prop is provided', done => {
it('should return `false` when `initialEpic` prop is provided', () => {
wrapper.setProps({
initialEpic: mockEpic1,
});
wrapper.vm.$nextTick(() => {
return wrapper.vm.$nextTick(() => {
expect(wrapper.vm.getInitialEpicLoading()).toBe(false);
done();
});
});
it('should return value of `sidebarStore.isFetching.epic` when `initialEpic` prop is null and `isFetching` is available', done => {
it('should return value of `sidebarStore.isFetching.epic` when `initialEpic` prop is null and `isFetching` is available', () => {
wrapper.setProps({
sidebarStore: { isFetching: { epic: true } },
});
wrapper.vm.$nextTick(() => {
return wrapper.vm.$nextTick(() => {
expect(wrapper.vm.getInitialEpicLoading()).toBe(true);
done();
});
});
it('should return `false` when both `initialEpic` and `sidebarStore.isFetching` are unavailable', done => {
it('should return `false` when both `initialEpic` and `sidebarStore.isFetching` are unavailable', () => {
wrapper.setProps({
initialEpic: null,
sidebarStore: { isFetching: null },
});
wrapper.vm.$nextTick(() => {
return wrapper.vm.$nextTick(() => {
expect(wrapper.vm.getInitialEpicLoading()).toBe(false);
done();
});
});
});
describe('getEpic', () => {
it('should return value of `initialEpic` as it is when it is available', done => {
it('should return value of `initialEpic` as it is when it is available', () => {
wrapper.setProps({
initialEpic: mockEpic1,
});
wrapper.vm.$nextTick(() => {
return wrapper.vm.$nextTick(() => {
expect(wrapper.vm.getEpic()).toBe(mockEpic1);
done();
});
});
......@@ -83,21 +79,19 @@ describe('SidebarItemEpicsSelect', () => {
expect(wrapper.vm.getEpic()).toBe(mockEpic1);
});
it('should return No Epic object as it is when both `initialEpic` & `sidebarStore.epic` are unavailable', done => {
it('should return No Epic object as it is when both `initialEpic` & `sidebarStore.epic` are unavailable', () => {
wrapper.setProps({
initialEpic: null,
sidebarStore: { epic: null },
});
wrapper.vm.$nextTick(() => {
return wrapper.vm.$nextTick(() => {
expect(wrapper.vm.getEpic()).toEqual(
expect.objectContaining({
id: 0,
title: 'none',
}),
);
done();
});
});
});
......
import Vue from 'vue';
import { escape } from 'underscore';
import ancestorsTree from 'ee/sidebar/components/ancestors_tree/ancestors_tree.vue';
import mountComponent from 'spec/helpers/vue_mount_component_helper';
import mountComponent from 'helpers/vue_mount_component_helper';
describe('AncestorsTreeContainer', () => {
let vm;
......@@ -29,50 +29,42 @@ describe('AncestorsTreeContainer', () => {
);
});
it('does not render timeline when fetching', done => {
it('does not render timeline when fetching', () => {
vm.$props.isFetching = true;
vm.$nextTick()
.then(() => {
expect(vm.$el.querySelector('.vertical-timeline')).toBeNull();
expect(vm.$el.querySelector('.value')).toBeNull();
})
.then(done)
.catch(done.fail);
return vm.$nextTick().then(() => {
expect(vm.$el.querySelector('.vertical-timeline')).toBeNull();
expect(vm.$el.querySelector('.value')).toBeNull();
});
});
it('render `None` when ancestors is an empty array', done => {
it('render `None` when ancestors is an empty array', () => {
vm.$props.ancestors = [];
vm.$nextTick()
.then(() => {
expect(vm.$el.querySelector('.vertical-timeline')).toBeNull();
expect(vm.$el.querySelector('.value')).not.toBeNull();
})
.then(done)
.catch(done.fail);
return vm.$nextTick().then(() => {
expect(vm.$el.querySelector('.vertical-timeline')).toBeNull();
expect(vm.$el.querySelector('.value')).not.toBeNull();
});
});
it('render loading icon when isFetching is true', done => {
it('render loading icon when isFetching is true', () => {
vm.$props.isFetching = true;
vm.$nextTick()
.then(() => {
expect(vm.$el.querySelector('.fa-spinner')).toBeDefined();
})
.then(done)
.catch(done.fail);
return vm.$nextTick().then(() => {
expect(vm.$el.querySelector('.fa-spinner')).toBeDefined();
});
});
it('escapes html in the tooltip', done => {
it('escapes html in the tooltip', () => {
const title = '<script>alert(1);</script>';
const escapedTitle = escape(title);
vm.$props.ancestors = [{ id: 1, url: '', title, state: 'open' }];
vm.$nextTick()
.then(() => {
const tooltip = vm.$el.querySelector('.collapse-truncated-title');
expect(tooltip.innerText).toBe(escapedTitle);
})
.then(done)
.catch(done.fail);
return vm.$nextTick().then(() => {
const tooltip = vm.$el.querySelector('.collapse-truncated-title');
expect(tooltip.innerText).toBe(escapedTitle);
});
});
});
import CEMockData from 'spec/sidebar/mock_data';
import CEMockData from 'jest/sidebar/mock_data';
const RESPONSE_MAP = { ...CEMockData.responseMap };
......
......@@ -3,7 +3,7 @@ import CESidebarMediator from '~/sidebar/sidebar_mediator';
import CESidebarStore from '~/sidebar/stores/sidebar_store';
import SidebarService from '~/sidebar/services/sidebar_service';
import Mock from './ee_mock_data';
import waitForPromises from 'spec/helpers/wait_for_promises';
import waitForPromises from 'helpers/wait_for_promises';
describe('EE Sidebar mediator', () => {
let mediator;
......@@ -31,7 +31,7 @@ describe('EE Sidebar mediator', () => {
it('updates status when updateStatus is called', () => {
const healthStatus = 'onTrack';
spyOn(mediator.service, 'updateWithGraphQl').and.returnValue(
jest.spyOn(mediator.service, 'updateWithGraphQl').mockReturnValue(
Promise.resolve({
data: {
updateIssue: {
......
......@@ -37,11 +37,11 @@ describe('EE Sidebar store', () => {
describe('setStatus', () => {
it('sets status', () => {
expect(store.status).toEqual('');
expect(store.status).toBe('');
const status = 'onTrack';
store.setStatus(status);
expect(store.status).toEqual(status);
expect(store.status).toBe(status);
});
});
......
......@@ -2,12 +2,12 @@ import Vue from 'vue';
import sidebarWeight from 'ee/sidebar/components/weight/sidebar_weight.vue';
import SidebarMediator from 'ee/sidebar/sidebar_mediator';
import SidebarStore from 'ee/sidebar/stores/sidebar_store';
import mountComponent from 'spec/helpers/vue_mount_component_helper';
import mountComponent from 'helpers/vue_mount_component_helper';
import SidebarService from '~/sidebar/services/sidebar_service';
import eventHub from '~/sidebar/event_hub';
import Mock from './ee_mock_data';
describe('Sidebar Weight', function() {
describe('Sidebar Weight', () => {
let vm;
let sidebarMediator;
let SidebarWeight;
......@@ -26,7 +26,7 @@ describe('Sidebar Weight', function() {
});
it('calls the mediator updateWeight on event', () => {
spyOn(SidebarMediator.prototype, 'updateWeight').and.returnValue(Promise.resolve());
jest.spyOn(SidebarMediator.prototype, 'updateWeight').mockReturnValue(Promise.resolve());
vm = mountComponent(SidebarWeight, {
mediator: sidebarMediator,
});
......
import Vue from 'vue';
import weight from 'ee/sidebar/components/weight/weight.vue';
import mountComponent from 'spec/helpers/vue_mount_component_helper';
import { mockTracking, triggerEvent } from 'spec/helpers/tracking_helper';
import mountComponent from 'helpers/vue_mount_component_helper';
import { mockTracking, unmockTracking, triggerEvent } from 'helpers/tracking_helper';
import eventHub from '~/sidebar/event_hub';
import { ENTER_KEY_CODE } from '~/lib/utils/keycodes';
......@@ -9,14 +9,12 @@ const DEFAULT_PROPS = {
weightNoneValue: 'None',
};
describe('Weight', function() {
describe('Weight', () => {
let vm;
let Weight;
let trackingSpy;
beforeEach(() => {
Weight = Vue.extend(weight);
trackingSpy = mockTracking('_category_', null, spyOn);
});
afterEach(() => {
......@@ -53,11 +51,11 @@ describe('Weight', function() {
weight: WEIGHT,
});
expect(vm.$el.querySelector('.js-weight-collapsed-weight-label').textContent.trim()).toEqual(
expect(vm.$el.querySelector('.js-weight-collapsed-weight-label').textContent.trim()).toBe(
`${WEIGHT}`,
);
expect(vm.$el.querySelector('.js-weight-weight-label-value').textContent.trim()).toEqual(
expect(vm.$el.querySelector('.js-weight-weight-label-value').textContent.trim()).toBe(
`${WEIGHT}`,
);
});
......@@ -70,68 +68,46 @@ describe('Weight', function() {
weight: WEIGHT,
});
expect(vm.$el.querySelector('.js-weight-collapsed-weight-label').textContent.trim()).toEqual(
expect(vm.$el.querySelector('.js-weight-collapsed-weight-label').textContent.trim()).toBe(
'None',
);
expect(vm.$el.querySelector('.js-weight-weight-label .no-value').textContent.trim()).toEqual(
expect(vm.$el.querySelector('.js-weight-weight-label .no-value').textContent.trim()).toBe(
'None',
);
});
it('adds `collapse-after-update` class when clicking the collapsed block', done => {
it('adds `collapse-after-update` class when clicking the collapsed block', () => {
vm = mountComponent(Weight, {
...DEFAULT_PROPS,
});
vm.$el.querySelector('.js-weight-collapsed-block').click();
vm.$nextTick()
.then(() => {
expect(vm.$el.classList.contains('collapse-after-update')).toEqual(true);
})
.then(done)
.catch(done.fail);
return vm.$nextTick().then(() => {
expect(vm.$el.classList.contains('collapse-after-update')).toBe(true);
});
});
it('shows dropdown on "Edit" link click', done => {
it('shows dropdown on "Edit" link click', () => {
vm = mountComponent(Weight, {
...DEFAULT_PROPS,
editable: true,
});
expect(vm.shouldShowEditField).toEqual(false);
expect(vm.shouldShowEditField).toBe(false);
vm.$el.querySelector('.js-weight-edit-link').click();
vm.$nextTick()
.then(() => {
expect(vm.shouldShowEditField).toEqual(true);
})
.then(done)
.catch(done.fail);
});
it('calls trackEvent when "Edit" is clicked', done => {
vm = mountComponent(Weight, {
...DEFAULT_PROPS,
editable: true,
return vm.$nextTick().then(() => {
expect(vm.shouldShowEditField).toBe(true);
});
triggerEvent(vm.$el.querySelector('.js-weight-edit-link'));
vm.$nextTick()
.then(() => {
expect(trackingSpy).toHaveBeenCalled();
})
.then(done)
.catch(done.fail);
});
it('emits event on input submission', done => {
it('emits event on input submission', () => {
const ID = 123;
const expectedWeightValue = '3';
spyOn(eventHub, '$emit');
jest.spyOn(eventHub, '$emit').mockImplementation(() => {});
vm = mountComponent(Weight, {
...DEFAULT_PROPS,
editable: true,
......@@ -140,7 +116,7 @@ describe('Weight', function() {
vm.$el.querySelector('.js-weight-edit-link').click();
vm.$nextTick(() => {
return vm.$nextTick(() => {
const event = new CustomEvent('keydown');
event.keyCode = ENTER_KEY_CODE;
......@@ -150,13 +126,12 @@ describe('Weight', function() {
expect(vm.hasValidInput).toBe(true);
expect(eventHub.$emit).toHaveBeenCalledWith('updateWeight', expectedWeightValue, ID);
done();
});
});
it('emits event on remove weight link click', done => {
it('emits event on remove weight link click', () => {
const ID = 123;
spyOn(eventHub, '$emit');
jest.spyOn(eventHub, '$emit').mockImplementation(() => {});
vm = mountComponent(Weight, {
...DEFAULT_PROPS,
editable: true,
......@@ -166,14 +141,13 @@ describe('Weight', function() {
vm.$el.querySelector('.js-weight-remove-link').click();
vm.$nextTick(() => {
return vm.$nextTick(() => {
expect(vm.hasValidInput).toBe(true);
expect(eventHub.$emit).toHaveBeenCalledWith('updateWeight', '', ID);
done();
});
});
it('triggers error on invalid negative integer value', done => {
it('triggers error on invalid negative integer value', () => {
vm = mountComponent(Weight, {
...DEFAULT_PROPS,
editable: true,
......@@ -181,7 +155,7 @@ describe('Weight', function() {
vm.$el.querySelector('.js-weight-edit-link').click();
vm.$nextTick(() => {
return vm.$nextTick(() => {
const event = new CustomEvent('keydown');
event.keyCode = ENTER_KEY_CODE;
......@@ -190,7 +164,32 @@ describe('Weight', function() {
vm.$refs.editableField.dispatchEvent(event);
expect(vm.hasValidInput).toBe(false);
done();
});
});
describe('tracking', () => {
let trackingSpy;
beforeEach(() => {
vm = mountComponent(Weight, {
...DEFAULT_PROPS,
editable: true,
});
trackingSpy = mockTracking('_category_', vm.$el, (obj, what) =>
jest.spyOn(obj, what).mockImplementation(() => {}),
);
});
afterEach(() => {
unmockTracking();
});
it('calls trackEvent when "Edit" is clicked', () => {
triggerEvent(vm.$el.querySelector('.js-weight-edit-link'));
return vm.$nextTick().then(() => {
expect(trackingSpy).toHaveBeenCalled();
});
});
});
});
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