Commit 5d31e16e authored by Illya Klymov's avatar Illya Klymov

Refactor diff_content to Jest

parent 69cb23c6
...@@ -45,7 +45,6 @@ export default { ...@@ -45,7 +45,6 @@ export default {
computed: { computed: {
...mapState({ ...mapState({
projectPath: state => state.diffs.projectPath, projectPath: state => state.diffs.projectPath,
endpoint: state => state.diffs.endpoint,
}), }),
...mapGetters('diffs', ['isInlineView', 'isParallelView']), ...mapGetters('diffs', ['isInlineView', 'isParallelView']),
...mapGetters('diffs', ['getCommentFormForDiffFile']), ...mapGetters('diffs', ['getCommentFormForDiffFile']),
......
import { shallowMount, createLocalVue } from '@vue/test-utils';
import Vuex from 'vuex';
import { GlLoadingIcon } from '@gitlab/ui';
import DiffContentComponent from '~/diffs/components/diff_content.vue';
import InlineDiffView from '~/diffs/components/inline_diff_view.vue';
import NotDiffableViewer from '~/vue_shared/components/diff_viewer/viewers/not_diffable.vue';
import NoPreviewViewer from '~/vue_shared/components/diff_viewer/viewers/no_preview.vue';
import ParallelDiffView from '~/diffs/components/parallel_diff_view.vue';
import ImageDiffOverlay from '~/diffs/components/image_diff_overlay.vue';
import NoteForm from '~/notes/components/note_form.vue';
import DiffDiscussions from '~/diffs/components/diff_discussions.vue';
import { IMAGE_DIFF_POSITION_TYPE } from '~/diffs/constants';
import diffFileMockData from '../../../javascripts/diffs/mock_data/diff_file';
import { diffViewerModes } from '~/ide/constants';
const localVue = createLocalVue();
localVue.use(Vuex);
describe('DiffContent', () => {
let wrapper;
const saveDiffDiscussionMock = jest.fn();
const closeDiffFileCommentFormMock = jest.fn();
const noteableTypeGetterMock = jest.fn();
const getUserDataGetterMock = jest.fn();
const isInlineViewGetterMock = jest.fn();
const isParallelViewGetterMock = jest.fn();
const getCommentFormForDiffFileGetterMock = jest.fn();
const defaultProps = {
diffFile: JSON.parse(JSON.stringify(diffFileMockData)),
};
const createComponent = ({ props, state } = {}) => {
const fakeStore = new Vuex.Store({
getters: {
getNoteableData() {
return {
current_user: {
can_create_note: true,
},
};
},
noteableType: noteableTypeGetterMock,
getUserData: getUserDataGetterMock,
},
modules: {
/*
we need extra batchComments since vue-test-utils does not
stub async components properly
*/
batchComments: {
namespaced: true,
getters: {
draftsForFile: () => () => true,
},
},
diffs: {
namespaced: true,
state: {
projectPath: 'project/path',
endpoint: 'endpoint',
...state,
},
getters: {
isInlineView: isInlineViewGetterMock,
isParallelView: isParallelViewGetterMock,
getCommentFormForDiffFile: getCommentFormForDiffFileGetterMock,
},
actions: {
saveDiffDiscussion: saveDiffDiscussionMock,
closeDiffFileCommentForm: closeDiffFileCommentFormMock,
},
},
},
});
wrapper = shallowMount(DiffContentComponent, {
propsData: {
...defaultProps,
...props,
},
localVue,
store: fakeStore,
sync: false,
});
};
afterEach(() => {
wrapper.destroy();
wrapper = null;
});
describe('with text based files', () => {
afterEach(() => {
[isParallelViewGetterMock, isInlineViewGetterMock].forEach(m => m.mockRestore());
});
const textDiffFile = { ...defaultProps.diffFile, viewer: { name: diffViewerModes.text } };
it('should render diff inline view if `isInlineView` is true', () => {
isInlineViewGetterMock.mockReturnValue(true);
createComponent({ props: { diffFile: textDiffFile } });
expect(wrapper.find(InlineDiffView).exists()).toBe(true);
});
it('should render parallel view if `isParallelView` getter is true', () => {
isParallelViewGetterMock.mockReturnValue(true);
createComponent({ props: { diffFile: textDiffFile } });
expect(wrapper.find(ParallelDiffView).exists()).toBe(true);
});
it('renders rendering more lines loading icon', () => {
createComponent({ props: { diffFile: { ...textDiffFile, renderingLines: true } } });
expect(wrapper.find(GlLoadingIcon).exists()).toBe(true);
});
});
describe('with empty files', () => {
const emptyDiffFile = {
...defaultProps.diffFile,
viewer: { name: diffViewerModes.text },
highlighted_diff_lines: [],
parallel_diff_lines: [],
};
it('should render a no preview view if viewer set to no preview', () => {
createComponent({
props: { diffFile: { ...emptyDiffFile, viewer: { name: diffViewerModes.no_preview } } },
});
expect(wrapper.find(NoPreviewViewer).exists()).toBe(true);
});
it('should render not diffable view if viewer set to non_diffable', () => {
createComponent({
props: { diffFile: { ...emptyDiffFile, viewer: { name: diffViewerModes.not_diffable } } },
});
expect(wrapper.find(NotDiffableViewer).exists()).toBe(true);
});
});
describe('with image files', () => {
const imageDiffFile = { ...defaultProps.diffFile, viewer: { name: diffViewerModes.image } };
it('should have image diff view in place', () => {
getCommentFormForDiffFileGetterMock.mockReturnValue(() => true);
createComponent({ props: { diffFile: imageDiffFile } });
expect(wrapper.find(InlineDiffView).exists()).toBe(false);
expect(wrapper.find(ImageDiffOverlay).exists()).toBe(true);
});
it('renders diff file discussions', () => {
getCommentFormForDiffFileGetterMock.mockReturnValue(() => true);
createComponent({
props: {
diffFile: { ...imageDiffFile, discussions: [{ name: 'discussion-stub ' }] },
},
});
expect(wrapper.find(DiffDiscussions).exists()).toBe(true);
});
it('emits saveDiffDiscussion when note-form emits `handleFormUpdate`', () => {
const noteStub = {};
getCommentFormForDiffFileGetterMock.mockReturnValue(() => true);
const currentDiffFile = { ...imageDiffFile, discussions: [{ name: 'discussion-stub ' }] };
createComponent({
props: {
diffFile: currentDiffFile,
},
});
wrapper.find(NoteForm).vm.$emit('handleFormUpdate', noteStub);
expect(saveDiffDiscussionMock).toHaveBeenCalledWith(
expect.any(Object),
{
note: noteStub,
formData: {
noteableData: expect.any(Object),
diffFile: currentDiffFile,
positionType: IMAGE_DIFF_POSITION_TYPE,
x: undefined,
y: undefined,
width: undefined,
height: undefined,
noteableType: undefined,
},
},
undefined,
);
});
});
});
import Vue from 'vue';
import DiffContentComponent from '~/diffs/components/diff_content.vue';
import { createStore } from 'ee_else_ce/mr_notes/stores';
import { mountComponentWithStore } from 'spec/helpers/vue_mount_component_helper';
import { GREEN_BOX_IMAGE_URL, RED_BOX_IMAGE_URL } from 'spec/test_constants';
import '~/behaviors/markdown/render_gfm';
import diffFileMockData from '../mock_data/diff_file';
import discussionsMockData from '../mock_data/diff_discussions';
import { diffViewerModes } from '~/ide/constants';
describe('DiffContent', () => {
const Component = Vue.extend(DiffContentComponent);
let vm;
beforeEach(() => {
const store = createStore();
store.state.notes.noteableData = {
current_user: {
can_create_note: false,
},
preview_note_path: 'path/to/preview',
};
vm = mountComponentWithStore(Component, {
store,
props: {
diffFile: JSON.parse(JSON.stringify(diffFileMockData)),
},
});
});
afterEach(() => {
vm.$destroy();
});
describe('text based files', () => {
it('should render diff inline view', done => {
vm.$store.state.diffs.diffViewType = 'inline';
vm.$nextTick(() => {
expect(vm.$el.querySelectorAll('.js-diff-inline-view').length).toEqual(1);
done();
});
});
it('should render diff parallel view', done => {
vm.$store.state.diffs.diffViewType = 'parallel';
vm.$nextTick(() => {
expect(vm.$el.querySelectorAll('.parallel').length).toEqual(18);
done();
});
});
it('renders rendering more lines loading icon', done => {
vm.diffFile.renderingLines = true;
vm.$nextTick(() => {
expect(vm.$el.querySelector('.loading-container')).not.toBe(null);
done();
});
});
});
describe('empty files', () => {
beforeEach(() => {
vm.diffFile.highlighted_diff_lines = [];
vm.diffFile.parallel_diff_lines = [];
});
it('should render a no preview message if viewer returns no preview', done => {
vm.diffFile.viewer.name = diffViewerModes.no_preview;
vm.$nextTick(() => {
const block = vm.$el.querySelector('.diff-viewer .nothing-here-block');
expect(block).not.toBe(null);
expect(block.textContent.trim()).toContain('No preview for this file type');
done();
});
});
it('should render a not diffable message if viewer returns not diffable', done => {
vm.diffFile.viewer.name = diffViewerModes.not_diffable;
vm.$nextTick(() => {
const block = vm.$el.querySelector('.diff-viewer .nothing-here-block');
expect(block).not.toBe(null);
expect(block.textContent.trim()).toContain(
'This diff was suppressed by a .gitattributes entry',
);
done();
});
});
it('should not render multiple messages', done => {
vm.diffFile.b_mode = '100755';
vm.diffFile.viewer.name = diffViewerModes.mode_changed;
vm.$nextTick(() => {
expect(vm.$el.querySelectorAll('.nothing-here-block').length).toBe(1);
done();
});
});
it('should not render diff table', done => {
vm.diffFile.viewer.name = diffViewerModes.no_preview;
vm.$nextTick(() => {
expect(vm.$el.querySelector('table')).toBe(null);
done();
});
});
});
describe('Non-Text diffs', () => {
beforeEach(() => {
vm.diffFile.viewer.name = 'image';
});
describe('image diff', () => {
beforeEach(done => {
vm.diffFile.new_path = GREEN_BOX_IMAGE_URL;
vm.diffFile.new_sha = 'DEF';
vm.diffFile.old_path = RED_BOX_IMAGE_URL;
vm.diffFile.old_sha = 'ABC';
vm.diffFile.view_path = '';
vm.diffFile.discussions = [{ ...discussionsMockData }];
vm.$store.state.diffs.commentForms.push({
fileHash: vm.diffFile.file_hash,
x: 10,
y: 20,
width: 100,
height: 200,
});
vm.$nextTick(done);
});
it('should have image diff view in place', () => {
expect(vm.$el.querySelectorAll('.js-diff-inline-view').length).toEqual(0);
expect(vm.$el.querySelectorAll('.diff-viewer .image').length).toEqual(1);
});
it('renders image diff overlay', () => {
expect(vm.$el.querySelector('.image-diff-overlay')).not.toBe(null);
});
it('renders diff file discussions', () => {
expect(vm.$el.querySelectorAll('.discussion .note.timeline-entry').length).toEqual(5);
});
describe('handleSaveNote', () => {
it('dispatches handleSaveNote', () => {
spyOn(vm.$store, 'dispatch').and.stub();
vm.handleSaveNote('test');
expect(vm.$store.dispatch).toHaveBeenCalledWith('diffs/saveDiffDiscussion', {
note: 'test',
formData: {
noteableData: jasmine.anything(),
noteableType: jasmine.anything(),
diffFile: vm.diffFile,
positionType: 'image',
x: 10,
y: 20,
width: 100,
height: 200,
},
});
});
});
});
describe('file diff', () => {
it('should have download buttons in place', done => {
const el = vm.$el;
vm.diffFile.new_path = 'test.abc';
vm.diffFile.new_sha = 'DEF';
vm.diffFile.old_path = 'test.abc';
vm.diffFile.old_sha = 'ABC';
vm.diffFile.viewer.name = diffViewerModes.added;
vm.$nextTick(() => {
expect(el.querySelectorAll('.js-diff-inline-view').length).toEqual(0);
expect(el.querySelector('.deleted .file-info').textContent.trim()).toContain('test.abc');
expect(el.querySelector('.deleted .btn.btn-default').textContent.trim()).toContain(
'Download',
);
expect(el.querySelector('.added .file-info').textContent.trim()).toContain('test.abc');
expect(el.querySelector('.added .btn.btn-default').textContent.trim()).toContain(
'Download',
);
done();
});
});
});
});
});
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