Refactor DiffFileHeader tests
* Switched from Karma to Jest * Reorganized tests to have correct semantics * Removed unused computed properties from component
This commit is contained in:
parent
42ce83bdd3
commit
bbdad735a0
4 changed files with 489 additions and 756 deletions
|
@ -57,26 +57,12 @@ export default {
|
|||
required: true,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
blobForkSuggestion: null,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapGetters('diffs', ['diffHasExpandedDiscussions', 'diffHasDiscussions']),
|
||||
hasExpandedDiscussions() {
|
||||
return this.diffHasExpandedDiscussions(this.diffFile);
|
||||
},
|
||||
diffContentIDSelector() {
|
||||
return `#diff-content-${this.diffFile.file_hash}`;
|
||||
},
|
||||
icon() {
|
||||
if (this.diffFile.submodule) {
|
||||
return 'archive';
|
||||
}
|
||||
|
||||
return this.diffFile.blob.icon;
|
||||
},
|
||||
titleLink() {
|
||||
if (this.diffFile.submodule) {
|
||||
return this.diffFile.submodule_tree_url || this.diffFile.submodule_link;
|
||||
|
@ -99,9 +85,6 @@ export default {
|
|||
|
||||
return this.diffFile.file_path;
|
||||
},
|
||||
titleTag() {
|
||||
return this.diffFile.file_hash ? 'a' : 'span';
|
||||
},
|
||||
isUsingLfs() {
|
||||
return this.diffFile.stored_externally && this.diffFile.external_storage === 'lfs';
|
||||
},
|
||||
|
@ -135,9 +118,6 @@ export default {
|
|||
isModeChanged() {
|
||||
return this.diffFile.viewer.name === diffViewerModes.mode_changed;
|
||||
},
|
||||
showExpandDiffToFullFileEnabled() {
|
||||
return gon.features.expandDiffFullFile && !this.diffFile.is_fully_expanded;
|
||||
},
|
||||
expandDiffToFullFileTitle() {
|
||||
if (this.diffFile.isShowingFullFile) {
|
||||
return s__('MRDiff|Show changes only');
|
||||
|
@ -156,21 +136,12 @@ export default {
|
|||
'toggleFileDiscussionWrappers',
|
||||
'toggleFullDiff',
|
||||
]),
|
||||
handleToggleFile(e, checkTarget) {
|
||||
if (
|
||||
!checkTarget ||
|
||||
e.target === this.$refs.header ||
|
||||
(e.target.classList && e.target.classList.contains('diff-toggle-caret'))
|
||||
) {
|
||||
this.$emit('toggleFile');
|
||||
}
|
||||
handleToggleFile() {
|
||||
this.$emit('toggleFile');
|
||||
},
|
||||
showForkMessage() {
|
||||
this.$emit('showForkMessage');
|
||||
},
|
||||
handleToggleDiscussions() {
|
||||
this.toggleFileDiscussionWrappers(this.diffFile);
|
||||
},
|
||||
handleFileNameClick(e) {
|
||||
const isLinkToOtherPage =
|
||||
this.diffFile.submodule_tree_url || this.diffFile.submodule_link || this.discussionPath;
|
||||
|
@ -178,7 +149,6 @@ export default {
|
|||
if (!isLinkToOtherPage) {
|
||||
e.preventDefault();
|
||||
const selector = this.diffContentIDSelector;
|
||||
|
||||
scrollToElement(document.querySelector(selector));
|
||||
window.location.hash = selector;
|
||||
}
|
||||
|
@ -191,22 +161,23 @@ export default {
|
|||
<div
|
||||
ref="header"
|
||||
class="js-file-title file-title file-title-flex-parent"
|
||||
@click="handleToggleFile($event, true)"
|
||||
@click.self="handleToggleFile"
|
||||
>
|
||||
<div class="file-header-content">
|
||||
<icon
|
||||
v-if="collapsible"
|
||||
ref="collapseIcon"
|
||||
:name="collapseIcon"
|
||||
:size="16"
|
||||
aria-hidden="true"
|
||||
class="diff-toggle-caret append-right-5"
|
||||
@click.stop="handleToggle"
|
||||
@click.stop="handleToggleFile"
|
||||
/>
|
||||
<a
|
||||
v-once
|
||||
id="diffFile.file_path"
|
||||
ref="titleWrapper"
|
||||
class="append-right-4 js-title-wrapper"
|
||||
class="append-right-4"
|
||||
:href="titleLink"
|
||||
@click="handleFileNameClick"
|
||||
>
|
||||
|
@ -214,7 +185,7 @@ export default {
|
|||
:file-name="filePath"
|
||||
:size="18"
|
||||
aria-hidden="true"
|
||||
css-classes="js-file-icon append-right-5"
|
||||
css-classes="append-right-5"
|
||||
/>
|
||||
<span v-if="isFileRenamed">
|
||||
<strong
|
||||
|
@ -260,12 +231,13 @@ export default {
|
|||
<template v-if="diffFile.blob && diffFile.blob.readable_text">
|
||||
<span v-gl-tooltip.hover :title="s__('MergeRequests|Toggle comments for this file')">
|
||||
<gl-button
|
||||
ref="toggleDiscussionsButton"
|
||||
:disabled="!diffHasDiscussions(diffFile)"
|
||||
:class="{ active: hasExpandedDiscussions }"
|
||||
:class="{ active: diffHasExpandedDiscussions(diffFile) }"
|
||||
class="js-btn-vue-toggle-comments btn"
|
||||
data-qa-selector="toggle_comments_button"
|
||||
type="button"
|
||||
@click="handleToggleDiscussions"
|
||||
@click="toggleFileDiscussionWrappers(diffFile)"
|
||||
>
|
||||
<icon name="comment" />
|
||||
</gl-button>
|
||||
|
@ -282,8 +254,9 @@ export default {
|
|||
|
||||
<a
|
||||
v-if="diffFile.replaced_view_path"
|
||||
ref="replacedFileButton"
|
||||
:href="diffFile.replaced_view_path"
|
||||
class="btn view-file js-view-replaced-file"
|
||||
class="btn view-file"
|
||||
v-html="viewReplacedFileButtonText"
|
||||
>
|
||||
</a>
|
||||
|
@ -292,7 +265,7 @@ export default {
|
|||
ref="expandDiffToFullFileButton"
|
||||
v-gl-tooltip.hover
|
||||
:title="expandDiffToFullFileTitle"
|
||||
class="expand-file js-expand-file"
|
||||
class="expand-file"
|
||||
@click="toggleFullDiff(diffFile.file_path)"
|
||||
>
|
||||
<gl-loading-icon v-if="diffFile.isLoadingFullFile" color="dark" inline />
|
||||
|
@ -304,7 +277,7 @@ export default {
|
|||
v-gl-tooltip.hover
|
||||
:href="diffFile.view_path"
|
||||
target="blank"
|
||||
class="view-file js-view-file-button"
|
||||
class="view-file"
|
||||
:title="viewFileButtonText"
|
||||
>
|
||||
<icon name="doc-text" />
|
||||
|
@ -312,12 +285,13 @@ export default {
|
|||
|
||||
<a
|
||||
v-if="diffFile.external_url"
|
||||
ref="externalLink"
|
||||
v-gl-tooltip.hover
|
||||
:href="diffFile.external_url"
|
||||
:title="`View on ${diffFile.formatted_external_url}`"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="btn btn-file-option js-external-url"
|
||||
class="btn btn-file-option"
|
||||
>
|
||||
<icon name="external-link" />
|
||||
</a>
|
||||
|
|
472
spec/frontend/diffs/components/diff_file_header_spec.js
Normal file
472
spec/frontend/diffs/components/diff_file_header_spec.js
Normal file
|
@ -0,0 +1,472 @@
|
|||
import { shallowMount, createLocalVue } from '@vue/test-utils';
|
||||
import Vuex from 'vuex';
|
||||
import DiffFileHeader from '~/diffs/components/diff_file_header.vue';
|
||||
import EditButton from '~/diffs/components/edit_button.vue';
|
||||
import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';
|
||||
import Icon from '~/vue_shared/components/icon.vue';
|
||||
import diffDiscussionsMockData from '../mock_data/diff_discussions';
|
||||
import { truncateSha } from '~/lib/utils/text_utility';
|
||||
import { diffViewerModes } from '~/ide/constants';
|
||||
import { __, sprintf } from '~/locale';
|
||||
import { scrollToElement } from '~/lib/utils/common_utils';
|
||||
|
||||
jest.mock('~/lib/utils/common_utils');
|
||||
|
||||
const diffFile = Object.freeze(
|
||||
Object.assign(diffDiscussionsMockData.diff_file, {
|
||||
edit_path: 'link:/to/edit/path',
|
||||
blob: {
|
||||
id: '848ed9407c6730ff16edb3dd24485a0eea24292a',
|
||||
path: 'lib/base.js',
|
||||
name: 'base.js',
|
||||
mode: '100644',
|
||||
readable_text: true,
|
||||
icon: 'file-text-o',
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
||||
describe('DiffFileHeader component', () => {
|
||||
let wrapper;
|
||||
|
||||
const diffHasExpandedDiscussionsResultMock = jest.fn();
|
||||
const diffHasDiscussionsResultMock = jest.fn();
|
||||
const mockStoreConfig = {
|
||||
state: {},
|
||||
modules: {
|
||||
diffs: {
|
||||
namespaced: true,
|
||||
getters: {
|
||||
diffHasExpandedDiscussions: () => diffHasExpandedDiscussionsResultMock,
|
||||
diffHasDiscussions: () => diffHasDiscussionsResultMock,
|
||||
},
|
||||
actions: {
|
||||
toggleFileDiscussions: jest.fn(),
|
||||
toggleFileDiscussionWrappers: jest.fn(),
|
||||
toggleFullDiff: jest.fn(),
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
afterEach(() => {
|
||||
[
|
||||
diffHasDiscussionsResultMock,
|
||||
diffHasExpandedDiscussionsResultMock,
|
||||
...Object.values(mockStoreConfig.modules.diffs.actions),
|
||||
].forEach(mock => mock.mockReset());
|
||||
});
|
||||
|
||||
const findHeader = () => wrapper.find({ ref: 'header' });
|
||||
const findTitleLink = () => wrapper.find({ ref: 'titleWrapper' });
|
||||
const findExpandButton = () => wrapper.find({ ref: 'expandDiffToFullFileButton' });
|
||||
const findFileActions = () => wrapper.find('.file-actions');
|
||||
const findModeChangedLine = () => wrapper.find({ ref: 'fileMode' });
|
||||
const findLfsLabel = () => wrapper.find('.label-lfs');
|
||||
const findToggleDiscussionsButton = () => wrapper.find({ ref: 'toggleDiscussionsButton' });
|
||||
const findExternalLink = () => wrapper.find({ ref: 'externalLink' });
|
||||
const findReplacedFileButton = () => wrapper.find({ ref: 'replacedFileButton' });
|
||||
const findViewFileButton = () => wrapper.find({ ref: 'viewButton' });
|
||||
const findCollapseIcon = () => wrapper.find({ ref: 'collapseIcon' });
|
||||
|
||||
const findIconByName = iconName => {
|
||||
const icons = wrapper.findAll(Icon).filter(w => w.props('name') === iconName);
|
||||
if (icons.length === 0) return icons;
|
||||
if (icons.length > 1) {
|
||||
throw new Error(`Multiple icons found for ${iconName}`);
|
||||
}
|
||||
return icons.at(0);
|
||||
};
|
||||
|
||||
const createComponent = props => {
|
||||
const localVue = createLocalVue();
|
||||
localVue.use(Vuex);
|
||||
const store = new Vuex.Store(mockStoreConfig);
|
||||
|
||||
wrapper = shallowMount(DiffFileHeader, {
|
||||
propsData: {
|
||||
diffFile,
|
||||
canCurrentUserFork: false,
|
||||
...props,
|
||||
},
|
||||
localVue,
|
||||
store,
|
||||
sync: false,
|
||||
});
|
||||
};
|
||||
|
||||
it.each`
|
||||
visibility | collapsible
|
||||
${'visible'} | ${true}
|
||||
${'hidden'} | ${false}
|
||||
`('collapse toggle is $visibility if collapsible is $collapsible', ({ collapsible }) => {
|
||||
createComponent({ collapsible });
|
||||
expect(findCollapseIcon().exists()).toBe(collapsible);
|
||||
});
|
||||
|
||||
it.each`
|
||||
expanded | icon
|
||||
${true} | ${'chevron-down'}
|
||||
${false} | ${'chevron-right'}
|
||||
`('collapse icon is $icon if expanded is $expanded', ({ icon, expanded }) => {
|
||||
createComponent({ expanded, collapsible: true });
|
||||
expect(findCollapseIcon().props('name')).toBe(icon);
|
||||
});
|
||||
|
||||
it('when header is clicked emits toggleFile', () => {
|
||||
createComponent();
|
||||
findHeader().trigger('click');
|
||||
expect(wrapper.emitted().toggleFile).toBeDefined();
|
||||
});
|
||||
|
||||
it('when collapseIcon is clicked emits toggleFile', () => {
|
||||
createComponent({ collapsible: true });
|
||||
findCollapseIcon().vm.$emit('click', new Event('click'));
|
||||
expect(wrapper.emitted().toggleFile).toBeDefined();
|
||||
});
|
||||
|
||||
it('when other element in header is clicked does not emits toggleFile', () => {
|
||||
createComponent({ collapsible: true });
|
||||
findTitleLink().trigger('click');
|
||||
expect(wrapper.emitted().toggleFile).not.toBeDefined();
|
||||
});
|
||||
|
||||
it('displays a copy to clipboard button', () => {
|
||||
createComponent();
|
||||
expect(wrapper.find(ClipboardButton).exists()).toBe(true);
|
||||
});
|
||||
|
||||
describe('for submodule', () => {
|
||||
const submoduleDiffFile = {
|
||||
...diffFile,
|
||||
submodule: true,
|
||||
submodule_link: 'link://to/submodule',
|
||||
};
|
||||
|
||||
it('prefers submodule_tree_url over submodule_link for href', () => {
|
||||
const submoduleTreeUrl = 'some://tree/url';
|
||||
createComponent({
|
||||
discussionLink: 'discussionLink',
|
||||
diffFile: {
|
||||
...submoduleDiffFile,
|
||||
submodule_tree_url: 'some://tree/url',
|
||||
},
|
||||
});
|
||||
|
||||
expect(findTitleLink().attributes('href')).toBe(submoduleTreeUrl);
|
||||
});
|
||||
|
||||
it('uses submodule_link for href if submodule_tree_url does not exists', () => {
|
||||
const submoduleLink = 'link://to/submodule';
|
||||
createComponent({
|
||||
discussionLink: 'discussionLink',
|
||||
diffFile: submoduleDiffFile,
|
||||
});
|
||||
|
||||
expect(findTitleLink().attributes('href')).toBe(submoduleLink);
|
||||
});
|
||||
|
||||
it('uses file_path + SHA as link text', () => {
|
||||
createComponent({
|
||||
diffFile: submoduleDiffFile,
|
||||
});
|
||||
|
||||
expect(findTitleLink().text()).toContain(
|
||||
`${diffFile.file_path} @ ${truncateSha(diffFile.blob.id)}`,
|
||||
);
|
||||
});
|
||||
|
||||
it('does not render file actions', () => {
|
||||
createComponent({
|
||||
diffFile: submoduleDiffFile,
|
||||
addMergeRequestButtons: true,
|
||||
});
|
||||
expect(findFileActions().exists()).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('for any file', () => {
|
||||
const otherModes = Object.keys(diffViewerModes).filter(m => m !== 'mode_changed');
|
||||
|
||||
it('when edit button emits showForkMessage event it is re-emitted', () => {
|
||||
createComponent({
|
||||
addMergeRequestButtons: true,
|
||||
});
|
||||
wrapper.find(EditButton).vm.$emit('showForkMessage');
|
||||
expect(wrapper.emitted().showForkMessage).toBeDefined();
|
||||
});
|
||||
|
||||
it('for mode_changed file mode displays mode changes', () => {
|
||||
createComponent({
|
||||
diffFile: {
|
||||
...diffFile,
|
||||
a_mode: 'old-mode',
|
||||
b_mode: 'new-mode',
|
||||
viewer: {
|
||||
...diffFile.viewer,
|
||||
name: diffViewerModes.mode_changed,
|
||||
},
|
||||
},
|
||||
});
|
||||
expect(findModeChangedLine().text()).toMatch(/old-mode.+new-mode/);
|
||||
});
|
||||
|
||||
it.each(otherModes.map(m => [m]))('for %s file mode does not display mode changes', mode => {
|
||||
createComponent({
|
||||
diffFile: {
|
||||
...diffFile,
|
||||
a_mode: 'old-mode',
|
||||
b_mode: 'new-mode',
|
||||
viewer: {
|
||||
...diffFile.viewer,
|
||||
name: diffViewerModes[mode],
|
||||
},
|
||||
},
|
||||
});
|
||||
expect(findModeChangedLine().exists()).toBeFalsy();
|
||||
});
|
||||
|
||||
it('displays the LFS label for files stored in LFS', () => {
|
||||
createComponent({
|
||||
diffFile: { ...diffFile, stored_externally: true, external_storage: 'lfs' },
|
||||
});
|
||||
expect(findLfsLabel().exists()).toBe(true);
|
||||
});
|
||||
|
||||
it('does not display the LFS label for files stored in repository', () => {
|
||||
createComponent({
|
||||
diffFile: { ...diffFile, stored_externally: false },
|
||||
});
|
||||
expect(findLfsLabel().exists()).toBe(false);
|
||||
});
|
||||
|
||||
it('does not render view replaced file button if no replaced view path is present', () => {
|
||||
createComponent({
|
||||
diffFile: { ...diffFile, replaced_view_path: null },
|
||||
});
|
||||
expect(findReplacedFileButton().exists()).toBe(false);
|
||||
});
|
||||
|
||||
describe('when addMergeRequestButtons is false', () => {
|
||||
it('does not render file actions', () => {
|
||||
createComponent({ addMergeRequestButtons: false });
|
||||
expect(findFileActions().exists()).toBe(false);
|
||||
});
|
||||
it('should not render edit button', () => {
|
||||
createComponent({ addMergeRequestButtons: false });
|
||||
expect(wrapper.find(EditButton).exists()).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when addMergeRequestButtons is true', () => {
|
||||
describe('without discussions', () => {
|
||||
it('renders a disabled toggle discussions button', () => {
|
||||
diffHasDiscussionsResultMock.mockReturnValue(false);
|
||||
createComponent({ addMergeRequestButtons: true });
|
||||
expect(findToggleDiscussionsButton().attributes('disabled')).toBe('true');
|
||||
});
|
||||
});
|
||||
|
||||
describe('with discussions', () => {
|
||||
it('dispatches toggleFileDiscussionWrappers when user clicks on toggle discussions button', () => {
|
||||
diffHasDiscussionsResultMock.mockReturnValue(true);
|
||||
createComponent({ addMergeRequestButtons: true });
|
||||
expect(findToggleDiscussionsButton().attributes('disabled')).toBeFalsy();
|
||||
findToggleDiscussionsButton().vm.$emit('click');
|
||||
expect(
|
||||
mockStoreConfig.modules.diffs.actions.toggleFileDiscussionWrappers,
|
||||
).toHaveBeenCalledWith(expect.any(Object), diffFile, undefined);
|
||||
});
|
||||
});
|
||||
|
||||
it('should show edit button', () => {
|
||||
createComponent({
|
||||
addMergeRequestButtons: true,
|
||||
});
|
||||
expect(wrapper.find(EditButton).exists()).toBe(true);
|
||||
});
|
||||
|
||||
describe('view on environment button', () => {
|
||||
it('is displayed when external url is provided', () => {
|
||||
const externalUrl = 'link://to/external';
|
||||
const formattedExternalUrl = 'link://formatted';
|
||||
createComponent({
|
||||
diffFile: {
|
||||
...diffFile,
|
||||
external_url: externalUrl,
|
||||
formatted_external_url: formattedExternalUrl,
|
||||
},
|
||||
addMergeRequestButtons: true,
|
||||
});
|
||||
expect(findExternalLink().exists()).toBe(true);
|
||||
});
|
||||
|
||||
it('is hidden by default', () => {
|
||||
createComponent({ addMergeRequestButtons: true });
|
||||
expect(findExternalLink().exists()).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('without file blob', () => {
|
||||
beforeEach(() => {
|
||||
createComponent({ diffFile: { ...diffFile, blob: false } });
|
||||
});
|
||||
|
||||
it('should not render toggle discussions button', () => {
|
||||
expect(findToggleDiscussionsButton().exists()).toBe(false);
|
||||
});
|
||||
|
||||
it('should not render edit button', () => {
|
||||
expect(wrapper.find(EditButton).exists()).toBe(false);
|
||||
});
|
||||
});
|
||||
describe('with file blob', () => {
|
||||
it('should render correct file view button', () => {
|
||||
const viewPath = 'link://view-path';
|
||||
createComponent({
|
||||
diffFile: { ...diffFile, view_path: viewPath },
|
||||
addMergeRequestButtons: true,
|
||||
});
|
||||
expect(findViewFileButton().attributes('href')).toBe(viewPath);
|
||||
expect(findViewFileButton().attributes('data-original-title')).toEqual(
|
||||
`View file @ ${diffFile.content_sha.substr(0, 8)}`,
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('expand full file button', () => {
|
||||
describe('when diff is fully expanded', () => {
|
||||
it('is not rendered', () => {
|
||||
createComponent({
|
||||
diffFile: {
|
||||
...diffFile,
|
||||
is_fully_expanded: true,
|
||||
},
|
||||
});
|
||||
expect(findExpandButton().exists()).toBe(false);
|
||||
});
|
||||
});
|
||||
describe('when diff is not fully expanded', () => {
|
||||
const fullyNotExpandedFileProps = {
|
||||
diffFile: {
|
||||
...diffFile,
|
||||
is_fully_expanded: false,
|
||||
edit_path: 'link/to/edit/path.txt',
|
||||
isShowingFullFile: false,
|
||||
},
|
||||
addMergeRequestButtons: true,
|
||||
};
|
||||
|
||||
it.each`
|
||||
iconName | isShowingFullFile
|
||||
${'doc-expand'} | ${false}
|
||||
${'doc-changes'} | ${true}
|
||||
`(
|
||||
'shows $iconName when isShowingFullFile set to $isShowingFullFile',
|
||||
({ iconName, isShowingFullFile }) => {
|
||||
createComponent({
|
||||
...fullyNotExpandedFileProps,
|
||||
diffFile: { ...fullyNotExpandedFileProps.diffFile, isShowingFullFile },
|
||||
});
|
||||
expect(findIconByName(iconName).exists()).toBe(true);
|
||||
},
|
||||
);
|
||||
|
||||
it('renders expand to full file button if not showing full file already', () => {
|
||||
createComponent(fullyNotExpandedFileProps);
|
||||
expect(findExpandButton().exists()).toBe(true);
|
||||
});
|
||||
|
||||
it('renders loading icon when loading full file', () => {
|
||||
createComponent(fullyNotExpandedFileProps);
|
||||
expect(findExpandButton().exists()).toBe(true);
|
||||
});
|
||||
|
||||
it('toggles full diff on click', () => {
|
||||
createComponent(fullyNotExpandedFileProps);
|
||||
findExpandButton().vm.$emit('click');
|
||||
expect(mockStoreConfig.modules.diffs.actions.toggleFullDiff).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('uses discussionPath for link if it is defined', () => {
|
||||
const discussionPath = 'link://to/discussion';
|
||||
createComponent({
|
||||
discussionPath,
|
||||
});
|
||||
expect(findTitleLink().attributes('href')).toBe(discussionPath);
|
||||
});
|
||||
|
||||
it('uses local anchor for link as last resort', () => {
|
||||
createComponent();
|
||||
expect(findTitleLink().attributes('href')).toMatch(/^#diff-content/);
|
||||
});
|
||||
|
||||
describe('when local anchor for link is clicked', () => {
|
||||
beforeEach(() => {
|
||||
createComponent();
|
||||
});
|
||||
|
||||
it('scrolls to target', () => {
|
||||
findTitleLink().trigger('click');
|
||||
expect(scrollToElement).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('updates anchor in URL', () => {
|
||||
findTitleLink().trigger('click');
|
||||
expect(window.location.href).toMatch(/#diff-content/);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('for new file', () => {
|
||||
it('displays the path', () => {
|
||||
createComponent({ diffFile: { ...diffFile, new_file: true } });
|
||||
expect(findTitleLink().text()).toBe(diffFile.file_path);
|
||||
});
|
||||
});
|
||||
|
||||
describe('for deleted file', () => {
|
||||
it('displays the path', () => {
|
||||
createComponent({ diffFile: { ...diffFile, deleted_file: true } });
|
||||
expect(findTitleLink().text()).toBe(
|
||||
sprintf(__('%{filePath} deleted'), { filePath: diffFile.file_path }, false),
|
||||
);
|
||||
});
|
||||
|
||||
it('does not show edit button', () => {
|
||||
createComponent({ diffFile: { ...diffFile, deleted_file: true } });
|
||||
expect(wrapper.find(EditButton).exists()).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('for renamed file', () => {
|
||||
it('displays old and new path if the file was renamed', () => {
|
||||
createComponent({
|
||||
diffFile: {
|
||||
...diffFile,
|
||||
renamed_file: true,
|
||||
old_path_html: 'old',
|
||||
new_path_html: 'new',
|
||||
},
|
||||
});
|
||||
expect(findTitleLink().text()).toMatch(/^old.+new/s);
|
||||
});
|
||||
});
|
||||
|
||||
describe('for replaced file', () => {
|
||||
it('renders view replaced file button', () => {
|
||||
const replacedViewPath = 'some/path';
|
||||
createComponent({
|
||||
diffFile: {
|
||||
...diffFile,
|
||||
replaced_view_path: replacedViewPath,
|
||||
},
|
||||
addMergeRequestButtons: true,
|
||||
});
|
||||
expect(findReplacedFileButton().exists()).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -1,713 +0,0 @@
|
|||
import Vue from 'vue';
|
||||
import Vuex from 'vuex';
|
||||
import diffsModule from '~/diffs/store/modules';
|
||||
import notesModule from '~/notes/stores/modules';
|
||||
import DiffFileHeader from '~/diffs/components/diff_file_header.vue';
|
||||
import mountComponent, { mountComponentWithStore } from 'spec/helpers/vue_mount_component_helper';
|
||||
import diffDiscussionsMockData from '../mock_data/diff_discussions';
|
||||
import { diffViewerModes } from '~/ide/constants';
|
||||
|
||||
Vue.use(Vuex);
|
||||
|
||||
describe('diff_file_header', () => {
|
||||
let vm;
|
||||
let props;
|
||||
const diffDiscussionMock = diffDiscussionsMockData;
|
||||
const Component = Vue.extend(DiffFileHeader);
|
||||
|
||||
const store = new Vuex.Store({
|
||||
modules: {
|
||||
diffs: diffsModule(),
|
||||
notes: notesModule(),
|
||||
},
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
const diffFile = diffDiscussionMock.diff_file;
|
||||
|
||||
diffFile.added_lines = 2;
|
||||
diffFile.removed_lines = 1;
|
||||
|
||||
props = {
|
||||
diffFile: { ...diffFile },
|
||||
canCurrentUserFork: false,
|
||||
};
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
vm.$destroy();
|
||||
});
|
||||
|
||||
describe('computed', () => {
|
||||
describe('icon', () => {
|
||||
beforeEach(() => {
|
||||
props.diffFile.blob.icon = 'file-text-o';
|
||||
});
|
||||
|
||||
it('returns the blob icon for files', () => {
|
||||
props.diffFile.submodule = false;
|
||||
|
||||
vm = mountComponentWithStore(Component, { props, store });
|
||||
|
||||
expect(vm.icon).toBe(props.diffFile.blob.icon);
|
||||
});
|
||||
|
||||
it('returns the archive icon for submodules', () => {
|
||||
props.diffFile.submodule = true;
|
||||
|
||||
vm = mountComponentWithStore(Component, { props, store });
|
||||
|
||||
expect(vm.icon).toBe('archive');
|
||||
});
|
||||
});
|
||||
|
||||
describe('titleLink', () => {
|
||||
beforeEach(() => {
|
||||
props.discussionPath = 'link://to/discussion';
|
||||
Object.assign(props.diffFile, {
|
||||
submodule_link: 'link://to/submodule',
|
||||
submodule_tree_url: 'some://tree/url',
|
||||
});
|
||||
});
|
||||
|
||||
it('returns the discussionPath for files', () => {
|
||||
props.diffFile.submodule = false;
|
||||
|
||||
vm = mountComponentWithStore(Component, { props, store });
|
||||
|
||||
expect(vm.titleLink).toBe(props.discussionPath);
|
||||
});
|
||||
|
||||
it('returns the submoduleTreeUrl for submodules', () => {
|
||||
props.diffFile.submodule = true;
|
||||
|
||||
vm = mountComponentWithStore(Component, { props, store });
|
||||
|
||||
expect(vm.titleLink).toBe(props.diffFile.submodule_tree_url);
|
||||
});
|
||||
|
||||
it('returns the submoduleLink for submodules without submoduleTreeUrl', () => {
|
||||
Object.assign(props.diffFile, {
|
||||
submodule: true,
|
||||
submodule_tree_url: null,
|
||||
});
|
||||
|
||||
vm = mountComponentWithStore(Component, { props, store });
|
||||
|
||||
expect(vm.titleLink).toBe(props.diffFile.submodule_link);
|
||||
});
|
||||
|
||||
it('sets the correct path to the discussion', () => {
|
||||
props.discussionPath = 'link://to/discussion';
|
||||
vm = mountComponentWithStore(Component, { props, store });
|
||||
const href = vm.$el.querySelector('.js-title-wrapper').getAttribute('href');
|
||||
|
||||
expect(href).toBe(vm.discussionPath);
|
||||
});
|
||||
});
|
||||
|
||||
describe('filePath', () => {
|
||||
beforeEach(() => {
|
||||
Object.assign(props.diffFile, {
|
||||
blob: { id: 'b10b1db10b1d' },
|
||||
file_path: 'path/to/file',
|
||||
});
|
||||
});
|
||||
|
||||
it('returns the filePath for files', () => {
|
||||
props.diffFile.submodule = false;
|
||||
|
||||
vm = mountComponentWithStore(Component, { props, store });
|
||||
|
||||
expect(vm.filePath).toBe(props.diffFile.file_path);
|
||||
});
|
||||
|
||||
it('appends the truncated blob id for submodules', () => {
|
||||
props.diffFile.submodule = true;
|
||||
|
||||
vm = mountComponentWithStore(Component, { props, store });
|
||||
|
||||
expect(vm.filePath).toBe(
|
||||
`${props.diffFile.file_path} @ ${props.diffFile.blob.id.substr(0, 8)}`,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('titleTag', () => {
|
||||
it('returns a link tag if fileHash is set', () => {
|
||||
props.diffFile.file_hash = 'some hash';
|
||||
|
||||
vm = mountComponentWithStore(Component, { props, store });
|
||||
|
||||
expect(vm.titleTag).toBe('a');
|
||||
});
|
||||
|
||||
it('returns a span tag if fileHash is not set', () => {
|
||||
props.diffFile.file_hash = null;
|
||||
|
||||
vm = mountComponentWithStore(Component, { props, store });
|
||||
|
||||
expect(vm.titleTag).toBe('span');
|
||||
});
|
||||
});
|
||||
|
||||
describe('isUsingLfs', () => {
|
||||
beforeEach(() => {
|
||||
Object.assign(props.diffFile, {
|
||||
stored_externally: true,
|
||||
external_storage: 'lfs',
|
||||
});
|
||||
});
|
||||
|
||||
it('returns true if file is stored in LFS', () => {
|
||||
vm = mountComponentWithStore(Component, { props, store });
|
||||
|
||||
expect(vm.isUsingLfs).toBe(true);
|
||||
});
|
||||
|
||||
it('returns false if file is not stored externally', () => {
|
||||
props.diffFile.stored_externally = false;
|
||||
|
||||
vm = mountComponentWithStore(Component, { props, store });
|
||||
|
||||
expect(vm.isUsingLfs).toBe(false);
|
||||
});
|
||||
|
||||
it('returns false if file is not stored in LFS', () => {
|
||||
props.diffFile.external_storage = 'not lfs';
|
||||
|
||||
vm = mountComponentWithStore(Component, { props, store });
|
||||
|
||||
expect(vm.isUsingLfs).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('collapseIcon', () => {
|
||||
it('returns chevron-down if the diff is expanded', () => {
|
||||
props.expanded = true;
|
||||
|
||||
vm = mountComponentWithStore(Component, { props, store });
|
||||
|
||||
expect(vm.collapseIcon).toBe('chevron-down');
|
||||
});
|
||||
|
||||
it('returns chevron-right if the diff is collapsed', () => {
|
||||
props.expanded = false;
|
||||
|
||||
vm = mountComponentWithStore(Component, { props, store });
|
||||
|
||||
expect(vm.collapseIcon).toBe('chevron-right');
|
||||
});
|
||||
});
|
||||
|
||||
describe('viewFileButtonText', () => {
|
||||
it('contains the truncated content SHA', () => {
|
||||
const dummySha = 'deebd00f is no SHA';
|
||||
props.diffFile.content_sha = dummySha;
|
||||
|
||||
vm = mountComponentWithStore(Component, { props, store });
|
||||
|
||||
expect(vm.viewFileButtonText).not.toContain(dummySha);
|
||||
expect(vm.viewFileButtonText).toContain(dummySha.substr(0, 8));
|
||||
});
|
||||
});
|
||||
|
||||
describe('viewReplacedFileButtonText', () => {
|
||||
it('contains the truncated base SHA', () => {
|
||||
const dummySha = 'deadabba sings no more';
|
||||
props.diffFile.diff_refs.base_sha = dummySha;
|
||||
|
||||
vm = mountComponentWithStore(Component, { props, store });
|
||||
|
||||
expect(vm.viewReplacedFileButtonText).not.toContain(dummySha);
|
||||
expect(vm.viewReplacedFileButtonText).toContain(dummySha.substr(0, 8));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('methods', () => {
|
||||
describe('handleToggleFile', () => {
|
||||
beforeEach(() => {
|
||||
spyOn(vm, '$emit').and.stub();
|
||||
});
|
||||
|
||||
it('emits toggleFile if checkTarget is false', () => {
|
||||
vm.handleToggleFile(null, false);
|
||||
|
||||
expect(vm.$emit).toHaveBeenCalledWith('toggleFile');
|
||||
});
|
||||
|
||||
it('emits toggleFile if checkTarget is true and event target is header', () => {
|
||||
vm.handleToggleFile({ target: vm.$refs.header }, true);
|
||||
|
||||
expect(vm.$emit).toHaveBeenCalledWith('toggleFile');
|
||||
});
|
||||
|
||||
it('does not emit toggleFile if checkTarget is true and event target is not header', () => {
|
||||
vm.handleToggleFile({ target: 'not header' }, true);
|
||||
|
||||
expect(vm.$emit).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('handleFileNameClick', () => {
|
||||
let e;
|
||||
|
||||
beforeEach(() => {
|
||||
e = { preventDefault: () => {} };
|
||||
spyOn(e, 'preventDefault');
|
||||
});
|
||||
|
||||
describe('when file name links to other page', () => {
|
||||
it('does not call preventDefault if submodule tree url exists', () => {
|
||||
vm = mountComponent(Component, {
|
||||
...props,
|
||||
diffFile: { ...props.diffFile, submodule_tree_url: 'foobar.com' },
|
||||
});
|
||||
|
||||
vm.handleFileNameClick(e);
|
||||
|
||||
expect(e.preventDefault).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('does not call preventDefault if submodule_link exists', () => {
|
||||
vm = mountComponent(Component, {
|
||||
...props,
|
||||
diffFile: { ...props.diffFile, submodule_link: 'foobar.com' },
|
||||
});
|
||||
vm.handleFileNameClick(e);
|
||||
|
||||
expect(e.preventDefault).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('does not call preventDefault if discussionPath exists', () => {
|
||||
vm = mountComponent(Component, {
|
||||
...props,
|
||||
discussionPath: 'Foo bar',
|
||||
});
|
||||
|
||||
vm.handleFileNameClick(e);
|
||||
|
||||
expect(e.preventDefault).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('scrolling to diff', () => {
|
||||
let scrollToElement;
|
||||
let el;
|
||||
|
||||
beforeEach(() => {
|
||||
el = document.createElement('div');
|
||||
spyOn(document, 'querySelector').and.returnValue(el);
|
||||
scrollToElement = spyOnDependency(DiffFileHeader, 'scrollToElement');
|
||||
vm = mountComponent(Component, props);
|
||||
|
||||
vm.handleFileNameClick(e);
|
||||
});
|
||||
|
||||
it('calls scrollToElement with file content', () => {
|
||||
expect(scrollToElement).toHaveBeenCalledWith(el);
|
||||
});
|
||||
|
||||
it('element adds the content id to the window location', () => {
|
||||
expect(window.location.hash).toContain(props.diffFile.file_hash);
|
||||
});
|
||||
|
||||
it('calls preventDefault when button does not link to other page', () => {
|
||||
expect(e.preventDefault).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('template', () => {
|
||||
describe('collapse toggle', () => {
|
||||
const collapseToggle = () => vm.$el.querySelector('.diff-toggle-caret');
|
||||
|
||||
it('is visible if collapsible is true', () => {
|
||||
props.collapsible = true;
|
||||
|
||||
vm = mountComponentWithStore(Component, { props, store });
|
||||
|
||||
expect(collapseToggle()).not.toBe(null);
|
||||
});
|
||||
|
||||
it('is hidden if collapsible is false', () => {
|
||||
props.collapsible = false;
|
||||
|
||||
vm = mountComponentWithStore(Component, { props, store });
|
||||
|
||||
expect(collapseToggle()).toBe(null);
|
||||
});
|
||||
});
|
||||
|
||||
it('displays an file icon in the title', () => {
|
||||
vm = mountComponentWithStore(Component, { props, store });
|
||||
|
||||
expect(vm.$el.querySelector('svg.js-file-icon use').getAttribute('xlink:href')).toContain(
|
||||
'ruby',
|
||||
);
|
||||
});
|
||||
|
||||
describe('file paths', () => {
|
||||
const filePaths = () => vm.$el.querySelectorAll('.file-title-name');
|
||||
|
||||
it('displays the path of a added file', () => {
|
||||
props.diffFile.renamed_file = false;
|
||||
|
||||
vm = mountComponentWithStore(Component, { props, store });
|
||||
|
||||
expect(filePaths()).toHaveLength(1);
|
||||
expect(filePaths()[0]).toHaveText(props.diffFile.file_path);
|
||||
});
|
||||
|
||||
it('displays path for deleted file', () => {
|
||||
props.diffFile.renamed_file = false;
|
||||
props.diffFile.deleted_file = true;
|
||||
|
||||
vm = mountComponentWithStore(Component, { props, store });
|
||||
|
||||
expect(filePaths()).toHaveLength(1);
|
||||
expect(filePaths()[0]).toHaveText(`${props.diffFile.file_path} deleted`);
|
||||
});
|
||||
|
||||
it('displays old and new path if the file was renamed', () => {
|
||||
props.diffFile.renamed_file = true;
|
||||
|
||||
vm = mountComponentWithStore(Component, { props, store });
|
||||
|
||||
expect(filePaths()).toHaveLength(2);
|
||||
expect(filePaths()[0]).toHaveText(props.diffFile.old_path_html);
|
||||
expect(filePaths()[1]).toHaveText(props.diffFile.new_path_html);
|
||||
});
|
||||
});
|
||||
|
||||
it('displays a copy to clipboard button', () => {
|
||||
vm = mountComponentWithStore(Component, { props, store });
|
||||
|
||||
const button = vm.$el.querySelector('.btn-clipboard');
|
||||
|
||||
expect(button).not.toBe(null);
|
||||
expect(button.dataset.clipboardText).toBe('{"text":"CHANGELOG.rb","gfm":"`CHANGELOG.rb`"}');
|
||||
});
|
||||
|
||||
describe('file mode', () => {
|
||||
it('it displays old and new file mode if it changed', () => {
|
||||
props.diffFile.viewer.name = diffViewerModes.mode_changed;
|
||||
|
||||
vm = mountComponentWithStore(Component, { props, store });
|
||||
|
||||
const { fileMode } = vm.$refs;
|
||||
|
||||
expect(fileMode).not.toBe(undefined);
|
||||
expect(fileMode).toContainText(props.diffFile.a_mode);
|
||||
expect(fileMode).toContainText(props.diffFile.b_mode);
|
||||
});
|
||||
|
||||
it('does not display the file mode if it has not changed', () => {
|
||||
props.diffFile.viewer.name = diffViewerModes.text;
|
||||
|
||||
vm = mountComponentWithStore(Component, { props, store });
|
||||
|
||||
const { fileMode } = vm.$refs;
|
||||
|
||||
expect(fileMode).toBe(undefined);
|
||||
});
|
||||
});
|
||||
|
||||
describe('LFS label', () => {
|
||||
const lfsLabel = () => vm.$el.querySelector('.label-lfs');
|
||||
|
||||
it('displays the LFS label for files stored in LFS', () => {
|
||||
Object.assign(props.diffFile, {
|
||||
stored_externally: true,
|
||||
external_storage: 'lfs',
|
||||
});
|
||||
|
||||
vm = mountComponentWithStore(Component, { props, store });
|
||||
|
||||
expect(lfsLabel()).not.toBe(null);
|
||||
expect(lfsLabel()).toHaveText('LFS');
|
||||
});
|
||||
|
||||
it('does not display the LFS label for files stored in repository', () => {
|
||||
props.diffFile.stored_externally = false;
|
||||
|
||||
vm = mountComponentWithStore(Component, { props, store });
|
||||
|
||||
expect(lfsLabel()).toBe(null);
|
||||
});
|
||||
});
|
||||
|
||||
describe('edit button', () => {
|
||||
it('should not render edit button if addMergeRequestButtons is not true', () => {
|
||||
vm = mountComponentWithStore(Component, { props, store });
|
||||
|
||||
expect(vm.$el.querySelector('.js-edit-blob')).toEqual(null);
|
||||
});
|
||||
|
||||
it('should show edit button when file is editable', () => {
|
||||
props.addMergeRequestButtons = true;
|
||||
props.diffFile.edit_path = '/';
|
||||
vm = mountComponentWithStore(Component, { props, store });
|
||||
|
||||
expect(vm.$el.querySelector('.js-edit-blob')).not.toBe(null);
|
||||
});
|
||||
|
||||
it('should not show edit button when file is deleted', () => {
|
||||
props.addMergeRequestButtons = true;
|
||||
props.diffFile.deleted_file = true;
|
||||
props.diffFile.edit_path = '/';
|
||||
vm = mountComponentWithStore(Component, { props, store });
|
||||
|
||||
expect(vm.$el.querySelector('.js-edit-blob')).toEqual(null);
|
||||
});
|
||||
});
|
||||
|
||||
describe('addMergeRequestButtons', () => {
|
||||
beforeEach(() => {
|
||||
props.addMergeRequestButtons = true;
|
||||
props.diffFile.edit_path = '';
|
||||
});
|
||||
|
||||
describe('view on environment button', () => {
|
||||
const url = 'some.external.url/';
|
||||
const title = 'url.title';
|
||||
|
||||
it('displays link to external url', () => {
|
||||
props.diffFile.external_url = url;
|
||||
props.diffFile.formatted_external_url = title;
|
||||
|
||||
vm = mountComponentWithStore(Component, { props, store });
|
||||
|
||||
expect(vm.$el.querySelector(`a[href="${url}"]`)).not.toBe(null);
|
||||
expect(vm.$el.querySelector(`a[data-original-title="View on ${title}"]`)).not.toBe(null);
|
||||
});
|
||||
|
||||
it('hides link if no external url', () => {
|
||||
props.diffFile.external_url = '';
|
||||
props.diffFile.formattedExternal_url = title;
|
||||
|
||||
vm = mountComponentWithStore(Component, { props, store });
|
||||
|
||||
expect(vm.$el.querySelector(`a[data-original-title="View on ${title}"]`)).toBe(null);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('handles toggle discussions', () => {
|
||||
it('renders a disabled button when diff has no discussions', () => {
|
||||
const propsCopy = Object.assign({}, props);
|
||||
propsCopy.diffFile.submodule = false;
|
||||
propsCopy.diffFile.blob = {
|
||||
id: '848ed9407c6730ff16edb3dd24485a0eea24292a',
|
||||
path: 'lib/base.js',
|
||||
name: 'base.js',
|
||||
mode: '100644',
|
||||
readable_text: true,
|
||||
icon: 'file-text-o',
|
||||
};
|
||||
propsCopy.addMergeRequestButtons = true;
|
||||
propsCopy.diffFile.deleted_file = true;
|
||||
|
||||
vm = mountComponentWithStore(Component, {
|
||||
props: propsCopy,
|
||||
store,
|
||||
});
|
||||
|
||||
expect(
|
||||
vm.$el.querySelector('.js-btn-vue-toggle-comments').getAttribute('disabled'),
|
||||
).toEqual('disabled');
|
||||
});
|
||||
|
||||
describe('with discussions', () => {
|
||||
it('dispatches toggleFileDiscussionWrappers when user clicks on toggle discussions button', () => {
|
||||
const propsCopy = Object.assign({}, props);
|
||||
propsCopy.diffFile.submodule = false;
|
||||
propsCopy.diffFile.blob = {
|
||||
id: '848ed9407c6730ff16edb3dd24485a0eea24292a',
|
||||
path: 'lib/base.js',
|
||||
name: 'base.js',
|
||||
mode: '100644',
|
||||
readable_text: true,
|
||||
icon: 'file-text-o',
|
||||
};
|
||||
propsCopy.addMergeRequestButtons = true;
|
||||
propsCopy.diffFile.deleted_file = true;
|
||||
|
||||
const discussionGetter = () => [
|
||||
{
|
||||
...diffDiscussionMock,
|
||||
},
|
||||
];
|
||||
const notesModuleMock = notesModule();
|
||||
notesModuleMock.getters.discussions = discussionGetter;
|
||||
vm = mountComponentWithStore(Component, {
|
||||
props: propsCopy,
|
||||
store: new Vuex.Store({
|
||||
modules: {
|
||||
diffs: diffsModule(),
|
||||
notes: notesModuleMock,
|
||||
},
|
||||
}),
|
||||
});
|
||||
|
||||
spyOn(vm, 'toggleFileDiscussionWrappers');
|
||||
|
||||
vm.$el.querySelector('.js-btn-vue-toggle-comments').click();
|
||||
|
||||
expect(vm.toggleFileDiscussionWrappers).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('file actions', () => {
|
||||
it('should not render if diff file has a submodule', () => {
|
||||
props.diffFile.submodule = 'submodule';
|
||||
vm = mountComponentWithStore(Component, { props, store });
|
||||
|
||||
expect(vm.$el.querySelector('.file-actions')).toEqual(null);
|
||||
});
|
||||
|
||||
it('should not render if add merge request buttons is false', () => {
|
||||
props.addMergeRequestButtons = false;
|
||||
vm = mountComponentWithStore(Component, { props, store });
|
||||
|
||||
expect(vm.$el.querySelector('.file-actions')).toEqual(null);
|
||||
});
|
||||
|
||||
describe('with add merge request buttons enabled', () => {
|
||||
beforeEach(() => {
|
||||
props.addMergeRequestButtons = true;
|
||||
props.diffFile.edit_path = 'edit-path';
|
||||
});
|
||||
|
||||
const viewReplacedFileButton = () => vm.$el.querySelector('.js-view-replaced-file');
|
||||
const viewFileButton = () => vm.$el.querySelector('.js-view-file-button');
|
||||
const externalUrl = () => vm.$el.querySelector('.js-external-url');
|
||||
|
||||
it('should render if add merge request buttons is true and diff file does not have a submodule', () => {
|
||||
vm = mountComponentWithStore(Component, { props, store });
|
||||
|
||||
expect(vm.$el.querySelector('.file-actions')).not.toEqual(null);
|
||||
});
|
||||
|
||||
it('should not render view replaced file button if no replaced view path is present', () => {
|
||||
vm = mountComponentWithStore(Component, { props, store });
|
||||
|
||||
expect(viewReplacedFileButton()).toEqual(null);
|
||||
});
|
||||
|
||||
it('should render view replaced file button if replaced view path is present', () => {
|
||||
props.diffFile.replaced_view_path = 'replaced-view-path';
|
||||
vm = mountComponentWithStore(Component, { props, store });
|
||||
|
||||
expect(viewReplacedFileButton()).not.toEqual(null);
|
||||
expect(viewReplacedFileButton().getAttribute('href')).toBe('replaced-view-path');
|
||||
});
|
||||
|
||||
it('should render correct file view button path', () => {
|
||||
props.diffFile.view_path = 'view-path';
|
||||
vm = mountComponentWithStore(Component, { props, store });
|
||||
|
||||
expect(viewFileButton().getAttribute('href')).toBe('view-path');
|
||||
expect(viewFileButton().getAttribute('data-original-title')).toEqual(
|
||||
`View file @ ${props.diffFile.content_sha.substr(0, 8)}`,
|
||||
);
|
||||
});
|
||||
|
||||
it('should not render external url view link if diff file has no external url', () => {
|
||||
vm = mountComponentWithStore(Component, { props, store });
|
||||
|
||||
expect(externalUrl()).toEqual(null);
|
||||
});
|
||||
|
||||
it('should render external url view link if diff file has external url', () => {
|
||||
props.diffFile.external_url = 'external_url';
|
||||
vm = mountComponentWithStore(Component, { props, store });
|
||||
|
||||
expect(externalUrl()).not.toEqual(null);
|
||||
expect(externalUrl().getAttribute('href')).toBe('external_url');
|
||||
});
|
||||
});
|
||||
|
||||
describe('without file blob', () => {
|
||||
beforeEach(() => {
|
||||
props.diffFile.blob = null;
|
||||
props.addMergeRequestButtons = true;
|
||||
vm = mountComponentWithStore(Component, { props, store });
|
||||
});
|
||||
|
||||
it('should not render toggle discussions button', () => {
|
||||
expect(vm.$el.querySelector('.js-btn-vue-toggle-comments')).toEqual(null);
|
||||
});
|
||||
|
||||
it('should not render edit button', () => {
|
||||
expect(vm.$el.querySelector('.js-edit-blob')).toEqual(null);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('expand full file button', () => {
|
||||
beforeEach(() => {
|
||||
props.addMergeRequestButtons = true;
|
||||
props.diffFile.edit_path = '/';
|
||||
});
|
||||
|
||||
it('does not render button', () => {
|
||||
vm = mountComponentWithStore(Component, { props, store });
|
||||
|
||||
expect(vm.$el.querySelector('.js-expand-file')).toBe(null);
|
||||
});
|
||||
|
||||
it('renders button', () => {
|
||||
props.diffFile.is_fully_expanded = false;
|
||||
|
||||
vm = mountComponentWithStore(Component, { props, store });
|
||||
|
||||
expect(vm.$el.querySelector('.js-expand-file')).not.toBe(null);
|
||||
});
|
||||
|
||||
it('shows fully expanded text', () => {
|
||||
props.diffFile.is_fully_expanded = false;
|
||||
props.diffFile.isShowingFullFile = true;
|
||||
|
||||
vm = mountComponentWithStore(Component, { props, store });
|
||||
|
||||
expect(vm.$el.querySelector('.ic-doc-changes')).not.toBeNull();
|
||||
});
|
||||
|
||||
it('shows expand text', () => {
|
||||
props.diffFile.is_fully_expanded = false;
|
||||
|
||||
vm = mountComponentWithStore(Component, { props, store });
|
||||
|
||||
expect(vm.$el.querySelector('.ic-doc-expand')).not.toBeNull();
|
||||
});
|
||||
|
||||
it('renders loading icon', () => {
|
||||
props.diffFile.is_fully_expanded = false;
|
||||
props.diffFile.isLoadingFullFile = true;
|
||||
|
||||
vm = mountComponentWithStore(Component, { props, store });
|
||||
|
||||
expect(vm.$el.querySelector('.js-expand-file .loading-container')).not.toBe(null);
|
||||
});
|
||||
|
||||
it('calls toggleFullDiff on click', () => {
|
||||
props.diffFile.is_fully_expanded = false;
|
||||
|
||||
vm = mountComponentWithStore(Component, { props, store });
|
||||
|
||||
spyOn(vm.$store, 'dispatch').and.stub();
|
||||
|
||||
vm.$el.querySelector('.js-expand-file').click();
|
||||
|
||||
expect(vm.$store.dispatch).toHaveBeenCalledWith(
|
||||
'diffs/toggleFullDiff',
|
||||
props.diffFile.file_path,
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -206,7 +206,7 @@ describe('DiffsStoreActions', () => {
|
|||
position_type: 'text',
|
||||
},
|
||||
},
|
||||
hash: 'diff-content-1c497fbb3a46b78edf04cc2a2fa33f67e3ffbe2a',
|
||||
hash: 'ABC_123',
|
||||
},
|
||||
},
|
||||
],
|
||||
|
|
Loading…
Reference in a new issue