Commit 4d52ab97 authored by Natalia Tepluhina's avatar Natalia Tepluhina

Merge branch 'xanf-convert-jest-to-vtu-197945' into 'master'

Resolve "Convert Jest tests to use VTU in 'spec/frontend/ide/components'"

Closes #197945

See merge request gitlab-org/gitlab!23681
parents ad4246c1 532bc104
import Vue from 'vue'; import { shallowMount } from '@vue/test-utils';
import mountCompontent from 'helpers/vue_mount_component_helper';
import router from '~/ide/ide_router'; import router from '~/ide/ide_router';
import Item from '~/ide/components/branches/item.vue'; import Item from '~/ide/components/branches/item.vue';
import { getTimeago } from '~/lib/utils/datetime_utility'; import Icon from '~/vue_shared/components/icon.vue';
import Timeago from '~/vue_shared/components/time_ago_tooltip.vue';
import { projectData } from '../../mock_data'; import { projectData } from '../../mock_data';
const TEST_BRANCH = { const TEST_BRANCH = {
...@@ -12,45 +12,45 @@ const TEST_BRANCH = { ...@@ -12,45 +12,45 @@ const TEST_BRANCH = {
const TEST_PROJECT_ID = projectData.name_with_namespace; const TEST_PROJECT_ID = projectData.name_with_namespace;
describe('IDE branch item', () => { describe('IDE branch item', () => {
const Component = Vue.extend(Item); let wrapper;
let vm;
function createComponent(props = {}) {
beforeEach(() => { wrapper = shallowMount(Item, {
vm = mountCompontent(Component, { propsData: {
item: { ...TEST_BRANCH }, item: { ...TEST_BRANCH },
projectId: TEST_PROJECT_ID, projectId: TEST_PROJECT_ID,
isActive: false, isActive: false,
...props,
},
}); });
}); }
afterEach(() => { afterEach(() => {
vm.$destroy(); wrapper.destroy();
}); });
it('renders branch name and timeago', () => { describe('if not active', () => {
const timeText = getTimeago().format(TEST_BRANCH.committedDate); beforeEach(() => {
createComponent();
expect(vm.$el.textContent).toContain(TEST_BRANCH.name); });
expect(vm.$el.querySelector('time')).toHaveText(timeText); it('renders branch name and timeago', () => {
expect(vm.$el.querySelector('.ic-mobile-issue-close')).toBe(null); expect(wrapper.text()).toContain(TEST_BRANCH.name);
}); expect(wrapper.find(Timeago).props('time')).toBe(TEST_BRANCH.committedDate);
expect(wrapper.find(Icon).exists()).toBe(false);
});
it('renders link to branch', () => { it('renders link to branch', () => {
const expectedHref = router.resolve(`/project/${TEST_PROJECT_ID}/edit/${TEST_BRANCH.name}`) const expectedHref = router.resolve(`/project/${TEST_PROJECT_ID}/edit/${TEST_BRANCH.name}`)
.href; .href;
expect(vm.$el.textContent).toMatch('a'); expect(wrapper.text()).toMatch('a');
expect(vm.$el).toHaveAttr('href', expectedHref); expect(wrapper.attributes('href')).toBe(expectedHref);
});
}); });
it('renders icon if isActive', done => { it('renders icon if is not active', () => {
vm.isActive = true; createComponent({ isActive: true });
vm.$nextTick() expect(wrapper.find(Icon).exists()).toBe(true);
.then(() => {
expect(vm.$el.querySelector('.ic-mobile-issue-close')).not.toBe(null);
})
.then(done)
.catch(done.fail);
}); });
}); });
import Vue from 'vue'; import { shallowMount } from '@vue/test-utils';
import Icon from '~/vue_shared/components/icon.vue';
import ScrollButton from '~/ide/components/jobs/detail/scroll_button.vue'; import ScrollButton from '~/ide/components/jobs/detail/scroll_button.vue';
import mountComponent from '../../../../helpers/vue_mount_component_helper';
describe('IDE job log scroll button', () => { describe('IDE job log scroll button', () => {
const Component = Vue.extend(ScrollButton); let wrapper;
let vm;
const createComponent = props => {
beforeEach(() => { wrapper = shallowMount(ScrollButton, {
vm = mountComponent(Component, { propsData: {
direction: 'up', direction: 'up',
disabled: false, disabled: false,
...props,
},
}); });
}); };
afterEach(() => { afterEach(() => {
vm.$destroy(); wrapper.destroy();
}); });
describe('iconName', () => { describe.each`
['up', 'down'].forEach(direction => { direction | icon | title
it(`returns icon name for ${direction}`, () => { ${'up'} | ${'scroll_up'} | ${'Scroll to top'}
vm.direction = direction; ${'down'} | ${'scroll_down'} | ${'Scroll to bottom'}
`('for $direction direction', ({ direction, icon, title }) => {
beforeEach(() => createComponent({ direction }));
expect(vm.iconName).toBe(`scroll_${direction}`); it('returns proper icon name', () => {
}); expect(wrapper.find(Icon).props('name')).toBe(icon);
}); });
});
describe('tooltipTitle', () => { it('returns proper title', () => {
it('returns title for up', () => { expect(wrapper.attributes('data-original-title')).toBe(title);
expect(vm.tooltipTitle).toBe('Scroll to top');
});
it('returns title for down', () => {
vm.direction = 'down';
expect(vm.tooltipTitle).toBe('Scroll to bottom');
}); });
}); });
it('emits click event on click', () => { it('emits click event on click', () => {
jest.spyOn(vm, '$emit').mockImplementation(() => {}); createComponent();
vm.$el.querySelector('.btn-scroll').click();
expect(vm.$emit).toHaveBeenCalledWith('click'); wrapper.find('button').trigger('click');
expect(wrapper.emitted().click).toBeDefined();
}); });
it('disables button when disabled is true', done => { it('disables button when disabled is true', () => {
vm.disabled = true; createComponent({ disabled: true });
vm.$nextTick(() => { expect(wrapper.find('button').attributes('disabled')).toBe('disabled');
expect(vm.$el.querySelector('.btn-scroll').hasAttribute('disabled')).toBe(true);
done();
});
}); });
}); });
import Vue from 'vue'; import { shallowMount } from '@vue/test-utils';
import mountComponent from 'helpers/vue_mount_component_helper';
import { TEST_HOST } from 'helpers/test_constants'; import { TEST_HOST } from 'helpers/test_constants';
import { GlLoadingIcon } from '@gitlab/ui';
import ClientsideNavigator from '~/ide/components/preview/navigator.vue'; import ClientsideNavigator from '~/ide/components/preview/navigator.vue';
import { listen } from 'codesandbox-api';
jest.mock('codesandbox-api', () => ({
listen: jest.fn().mockReturnValue(jest.fn()),
}));
describe('IDE clientside preview navigator', () => { describe('IDE clientside preview navigator', () => {
let vm; let wrapper;
let Component;
let manager; let manager;
let listenHandler;
beforeAll(() => { const findBackButton = () => wrapper.findAll('button').at(0);
Component = Vue.extend(ClientsideNavigator); const findForwardButton = () => wrapper.findAll('button').at(1);
}); const findRefreshButton = () => wrapper.findAll('button').at(2);
beforeEach(() => { beforeEach(() => {
listen.mockClear();
manager = { bundlerURL: TEST_HOST, iframe: { src: '' } }; manager = { bundlerURL: TEST_HOST, iframe: { src: '' } };
vm = mountComponent(Component, { manager }); wrapper = shallowMount(ClientsideNavigator, { propsData: { manager } });
[[listenHandler]] = listen.mock.calls;
}); });
afterEach(() => { afterEach(() => {
vm.$destroy(); wrapper.destroy();
}); });
it('renders readonly URL bar', () => { it('renders readonly URL bar', () => {
expect(vm.$el.querySelector('input[readonly]').value).toBe('/'); listenHandler({ type: 'urlchange', url: manager.bundlerURL });
return wrapper.vm.$nextTick(() => {
expect(wrapper.find('input[readonly]').element.value).toBe('/');
});
}); });
it('disables back button when navigationStack is empty', () => { it('renders loading icon by default', () => {
expect(vm.$el.querySelector('.ide-navigator-btn')).toHaveAttr('disabled'); expect(wrapper.find(GlLoadingIcon).exists()).toBe(true);
expect(vm.$el.querySelector('.ide-navigator-btn').classList).toContain('disabled-content');
}); });
it('disables forward button when forwardNavigationStack is empty', () => { it('removes loading icon when done event is fired', () => {
vm.forwardNavigationStack = []; listenHandler({ type: 'done' });
return wrapper.vm.$nextTick(() => {
expect(vm.$el.querySelectorAll('.ide-navigator-btn')[1]).toHaveAttr('disabled'); expect(wrapper.find(GlLoadingIcon).exists()).toBe(false);
expect(vm.$el.querySelectorAll('.ide-navigator-btn')[1].classList).toContain( });
'disabled-content',
);
}); });
it('calls back method when clicking back button', done => { it('does not count visiting same url multiple times', () => {
vm.navigationStack.push('/test'); listenHandler({ type: 'done' });
vm.navigationStack.push('/test2'); listenHandler({ type: 'done', url: `${TEST_HOST}/url1` });
jest.spyOn(vm, 'back').mockReturnValue(); listenHandler({ type: 'done', url: `${TEST_HOST}/url1` });
return wrapper.vm.$nextTick().then(() => {
vm.$nextTick(() => { expect(findBackButton().attributes('disabled')).toBe('disabled');
vm.$el.querySelector('.ide-navigator-btn').click();
expect(vm.back).toHaveBeenCalled();
done();
}); });
}); });
it('calls forward method when clicking forward button', done => { it('unsubscribes from listen on destroy', () => {
vm.forwardNavigationStack.push('/test'); const unsubscribeFn = listen();
jest.spyOn(vm, 'forward').mockReturnValue();
vm.$nextTick(() => { wrapper.destroy();
vm.$el.querySelectorAll('.ide-navigator-btn')[1].click(); expect(unsubscribeFn).toHaveBeenCalled();
expect(vm.forward).toHaveBeenCalled();
done();
});
}); });
describe('onUrlChange', () => { describe('back button', () => {
it('updates the path', () => { beforeEach(() => {
vm.onUrlChange({ url: `${TEST_HOST}/url` }); listenHandler({ type: 'done' });
listenHandler({ type: 'urlchange', url: TEST_HOST });
expect(vm.path).toBe('/url'); return wrapper.vm.$nextTick();
}); });
it('sets currentBrowsingIndex 0 if not already set', () => { it('is disabled by default', () => {
vm.onUrlChange({ url: `${TEST_HOST}/url` }); expect(findBackButton().attributes('disabled')).toBe('disabled');
expect(vm.currentBrowsingIndex).toBe(0);
}); });
it('increases currentBrowsingIndex if path doesnt match', () => { it('is enabled when there is previous entry', () => {
vm.onUrlChange({ url: `${TEST_HOST}/url` }); listenHandler({ type: 'urlchange', url: `${TEST_HOST}/url1` });
return wrapper.vm.$nextTick().then(() => {
vm.onUrlChange({ url: `${TEST_HOST}/url2` }); findBackButton().trigger('click');
expect(findBackButton().attributes('disabled')).toBeFalsy();
expect(vm.currentBrowsingIndex).toBe(1); });
}); });
it('does not increase currentBrowsingIndex if path matches', () => { it('is disabled when there is no previous entry', () => {
vm.onUrlChange({ url: `${TEST_HOST}/url` }); listenHandler({ type: 'urlchange', url: `${TEST_HOST}/url1` });
return wrapper.vm
vm.onUrlChange({ url: `${TEST_HOST}/url` }); .$nextTick()
.then(() => {
expect(vm.currentBrowsingIndex).toBe(0); findBackButton().trigger('click');
return wrapper.vm.$nextTick();
})
.then(() => {
expect(findBackButton().attributes('disabled')).toBe('disabled');
});
}); });
it('pushes path into navigation stack', () => { it('updates manager iframe src', () => {
vm.onUrlChange({ url: `${TEST_HOST}/url` }); listenHandler({ type: 'urlchange', url: `${TEST_HOST}/url1` });
listenHandler({ type: 'urlchange', url: `${TEST_HOST}/url2` });
return wrapper.vm.$nextTick().then(() => {
findBackButton().trigger('click');
expect(vm.navigationStack).toEqual(['/url']); expect(manager.iframe.src).toBe(`${TEST_HOST}/url1`);
});
}); });
}); });
describe('back', () => { describe('forward button', () => {
beforeEach(() => { beforeEach(() => {
vm.path = '/test2'; listenHandler({ type: 'done' });
vm.currentBrowsingIndex = 1; listenHandler({ type: 'urlchange', url: TEST_HOST });
vm.navigationStack.push('/test'); return wrapper.vm.$nextTick();
vm.navigationStack.push('/test2');
jest.spyOn(vm, 'visitPath').mockReturnValue();
vm.back();
}); });
it('visits the last entry in navigationStack', () => { it('is disabled by default', () => {
expect(vm.visitPath).toHaveBeenCalledWith('/test'); expect(findForwardButton().attributes('disabled')).toBe('disabled');
}); });
it('adds last entry to forwardNavigationStack', () => { it('is enabled when there is next entry', () => {
expect(vm.forwardNavigationStack).toEqual(['/test2']); listenHandler({ type: 'urlchange', url: `${TEST_HOST}/url1` });
return wrapper.vm
.$nextTick()
.then(() => {
findBackButton().trigger('click');
return wrapper.vm.$nextTick();
})
.then(() => {
expect(findForwardButton().attributes('disabled')).toBeFalsy();
});
}); });
it('clears navigation stack if currentBrowsingIndex is 1', () => { it('is disabled when there is no next entry', () => {
expect(vm.navigationStack).toEqual([]); listenHandler({ type: 'urlchange', url: `${TEST_HOST}/url1` });
return wrapper.vm
.$nextTick()
.then(() => {
findBackButton().trigger('click');
return wrapper.vm.$nextTick();
})
.then(() => {
findForwardButton().trigger('click');
return wrapper.vm.$nextTick();
})
.then(() => {
expect(findForwardButton().attributes('disabled')).toBe('disabled');
});
}); });
it('sets currentBrowsingIndex to null is currentBrowsingIndex is 1', () => { it('updates manager iframe src', () => {
expect(vm.currentBrowsingIndex).toBe(null); listenHandler({ type: 'urlchange', url: `${TEST_HOST}/url1` });
}); listenHandler({ type: 'urlchange', url: `${TEST_HOST}/url2` });
}); return wrapper.vm.$nextTick().then(() => {
findBackButton().trigger('click');
describe('forward', () => {
it('calls visitPath with first entry in forwardNavigationStack', () => {
jest.spyOn(vm, 'visitPath').mockReturnValue();
vm.forwardNavigationStack.push('/test');
vm.forwardNavigationStack.push('/test2');
vm.forward(); expect(manager.iframe.src).toBe(`${TEST_HOST}/url1`);
});
expect(vm.visitPath).toHaveBeenCalledWith('/test');
}); });
}); });
describe('refresh', () => { describe('refresh button', () => {
it('calls refresh with current path', () => { const url = `${TEST_HOST}/some_url`;
jest.spyOn(vm, 'visitPath').mockReturnValue(); beforeEach(() => {
listenHandler({ type: 'done' });
vm.path = '/test'; listenHandler({ type: 'urlchange', url });
return wrapper.vm.$nextTick();
vm.refresh();
expect(vm.visitPath).toHaveBeenCalledWith('/test');
}); });
});
describe('visitPath', () => { it('calls refresh with current path', () => {
it('updates iframe src with passed in path', () => { manager.iframe.src = 'something-other';
vm.visitPath('/testpath'); findRefreshButton().trigger('click');
expect(manager.iframe.src).toBe(`${TEST_HOST}/testpath`); expect(manager.iframe.src).toBe(url);
}); });
}); });
}); });
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