import { shallowMount, mount } from '@vue/test-utils';
import { nextTick } from 'vue';
import Header from '~/vue_merge_request_widget/components/mr_widget_header.vue';
import WebIdeLink from '~/vue_shared/components/web_ide_link.vue';
describe('MRWidgetHeader', () => {
let wrapper;
const createComponent = (propsData = {}) => {
wrapper = shallowMount(Header, {
propsData,
});
};
afterEach(() => {
wrapper.destroy();
gon.relative_url_root = '';
});
const expectDownloadDropdownItems = () => {
const downloadEmailPatchesEl = wrapper.find('.js-download-email-patches');
const downloadPlainDiffEl = wrapper.find('.js-download-plain-diff');
expect(downloadEmailPatchesEl.text().trim()).toBe('Email patches');
expect(downloadEmailPatchesEl.attributes('href')).toBe('/mr/email-patches');
expect(downloadPlainDiffEl.text().trim()).toBe('Plain diff');
expect(downloadPlainDiffEl.attributes('href')).toBe('/mr/plainDiffPath');
};
const commonMrProps = {
divergedCommitsCount: 1,
sourceBranch: 'mr-widget-refactor',
sourceBranchLink: 'Link',
targetBranch: 'main',
targetBranchPath: '/foo/bar/main',
statusPath: 'abc',
};
const findWebIdeButton = () => wrapper.findComponent(WebIdeLink);
describe('computed', () => {
describe('shouldShowCommitsBehindText', () => {
it('return true when there are divergedCommitsCount', () => {
createComponent({
mr: {
divergedCommitsCount: 12,
sourceBranch: 'mr-widget-refactor',
sourceBranchLink: 'Link',
targetBranch: 'main',
statusPath: 'abc',
},
});
expect(wrapper.vm.shouldShowCommitsBehindText).toBe(true);
});
it('returns false where there are no divergedComits count', () => {
createComponent({
mr: {
divergedCommitsCount: 0,
sourceBranch: 'mr-widget-refactor',
sourceBranchLink: 'Link',
targetBranch: 'main',
statusPath: 'abc',
},
});
expect(wrapper.vm.shouldShowCommitsBehindText).toBe(false);
});
});
describe('commitsBehindText', () => {
it('returns singular when there is one commit', () => {
wrapper = mount(Header, {
propsData: {
mr: commonMrProps,
},
});
expect(wrapper.find('.diverged-commits-count').element.innerHTML).toBe(
'The source branch is 1 commit behind the target branch',
);
});
it('returns plural when there is more than one commit', () => {
wrapper = mount(Header, {
propsData: {
mr: {
...commonMrProps,
divergedCommitsCount: 2,
},
},
});
expect(wrapper.find('.diverged-commits-count').element.innerHTML).toBe(
'The source branch is 2 commits behind the target branch',
);
});
});
});
describe('template', () => {
describe('common elements', () => {
beforeEach(() => {
createComponent({
mr: {
divergedCommitsCount: 12,
sourceBranch: 'mr-widget-refactor',
sourceBranchLink: 'mr-widget-refactor',
sourceBranchRemoved: false,
targetBranchPath: 'foo/bar/commits-path',
targetBranchTreePath: 'foo/bar/tree/path',
targetBranch: 'main',
isOpen: true,
emailPatchesPath: '/mr/email-patches',
plainDiffPath: '/mr/plainDiffPath',
statusPath: 'abc',
},
});
});
it('renders source branch link', () => {
expect(wrapper.find('.js-source-branch').html()).toContain(
'mr-widget-refactor',
);
});
it('renders clipboard button', () => {
expect(wrapper.find('[data-testid="mr-widget-copy-clipboard"]')).not.toBe(null);
});
it('renders target branch', () => {
expect(wrapper.find('.js-target-branch').text().trim()).toBe('main');
});
});
describe('with an open merge request', () => {
const mrDefaultOptions = {
iid: 1,
divergedCommitsCount: 12,
sourceBranch: 'mr-widget-refactor',
sourceBranchLink: 'mr-widget-refactor',
sourceBranchRemoved: false,
targetBranchPath: 'foo/bar/commits-path',
targetBranchTreePath: 'foo/bar/tree/path',
targetBranch: 'main',
isOpen: true,
canPushToSourceBranch: true,
emailPatchesPath: '/mr/email-patches',
plainDiffPath: '/mr/plainDiffPath',
statusPath: 'abc',
sourceProjectFullPath: 'root/gitlab-ce',
targetProjectFullPath: 'gitlab-org/gitlab-ce',
gitpodEnabled: true,
showGitpodButton: true,
gitpodUrl: 'http://gitpod.localhost',
};
it('renders checkout branch button with modal trigger', () => {
createComponent({
mr: { ...mrDefaultOptions },
});
const button = wrapper.find('.js-check-out-branch');
expect(button.text().trim()).toBe('Check out branch');
});
it.each([
[
'renders web ide button',
{
mrProps: {},
relativeUrl: '',
webIdeUrl:
'/-/ide/project/root/gitlab-ce/merge_requests/1?target_project=gitlab-org%2Fgitlab-ce',
},
],
[
'renders web ide button with blank target_project, when mr has same target project',
{
mrProps: { targetProjectFullPath: 'root/gitlab-ce' },
relativeUrl: '',
webIdeUrl: '/-/ide/project/root/gitlab-ce/merge_requests/1?target_project=',
},
],
[
'renders web ide button with relative url',
{
mrProps: { iid: 2 },
relativeUrl: '/gitlab',
webIdeUrl:
'/gitlab/-/ide/project/root/gitlab-ce/merge_requests/2?target_project=gitlab-org%2Fgitlab-ce',
},
],
])('%s', async (_, { mrProps, relativeUrl, webIdeUrl }) => {
gon.relative_url_root = relativeUrl;
createComponent({
mr: { ...mrDefaultOptions, ...mrProps },
});
await nextTick();
expect(findWebIdeButton().props()).toMatchObject({
showEditButton: false,
showWebIdeButton: true,
webIdeText: 'Open in Web IDE',
gitpodText: 'Open in Gitpod',
gitpodEnabled: true,
showGitpodButton: true,
gitpodUrl: 'http://gitpod.localhost',
webIdeUrl,
});
});
it('does not render web ide button if source branch is removed', async () => {
createComponent({ mr: { ...mrDefaultOptions, sourceBranchRemoved: true } });
await nextTick();
expect(findWebIdeButton().exists()).toBe(false);
});
it('renders download dropdown with links', () => {
createComponent({
mr: { ...mrDefaultOptions },
});
expectDownloadDropdownItems();
});
});
describe('with a closed merge request', () => {
beforeEach(() => {
createComponent({
mr: {
divergedCommitsCount: 12,
sourceBranch: 'mr-widget-refactor',
sourceBranchLink: 'mr-widget-refactor',
sourceBranchRemoved: false,
targetBranchPath: 'foo/bar/commits-path',
targetBranchTreePath: 'foo/bar/tree/path',
targetBranch: 'main',
isOpen: false,
emailPatchesPath: '/mr/email-patches',
plainDiffPath: '/mr/plainDiffPath',
statusPath: 'abc',
},
});
});
it('does not render checkout branch button with modal trigger', () => {
const button = wrapper.find('.js-check-out-branch');
expect(button.exists()).toBe(false);
});
it('renders download dropdown with links', () => {
expectDownloadDropdownItems();
});
});
describe('without diverged commits', () => {
beforeEach(() => {
createComponent({
mr: {
divergedCommitsCount: 0,
sourceBranch: 'mr-widget-refactor',
sourceBranchLink: 'mr-widget-refactor',
sourceBranchRemoved: false,
targetBranchPath: 'foo/bar/commits-path',
targetBranchTreePath: 'foo/bar/tree/path',
targetBranch: 'main',
isOpen: true,
emailPatchesPath: '/mr/email-patches',
plainDiffPath: '/mr/plainDiffPath',
statusPath: 'abc',
},
});
});
it('does not render diverged commits info', () => {
expect(wrapper.find('.diverged-commits-count').exists()).toBe(false);
});
});
describe('with diverged commits', () => {
beforeEach(() => {
wrapper = mount(Header, {
propsData: {
mr: {
...commonMrProps,
divergedCommitsCount: 12,
sourceBranchRemoved: false,
targetBranchPath: 'foo/bar/commits-path',
targetBranchTreePath: 'foo/bar/tree/path',
isOpen: true,
emailPatchesPath: '/mr/email-patches',
plainDiffPath: '/mr/plainDiffPath',
},
},
});
});
it('renders diverged commits info', () => {
expect(wrapper.find('.diverged-commits-count').text().trim()).toBe(
'The source branch is 12 commits behind the target branch',
);
expect(wrapper.find('.diverged-commits-count a').text().trim()).toBe('12 commits behind');
expect(wrapper.find('.diverged-commits-count a').attributes('href')).toBe(
wrapper.vm.mr.targetBranchPath,
);
});
});
});
});