debian-mirror-gitlab/spec/frontend/diffs/store/actions_spec.js

1351 lines
36 KiB
JavaScript
Raw Normal View History

2018-11-08 19:23:39 +05:30
import MockAdapter from 'axios-mock-adapter';
import Cookies from 'js-cookie';
2020-04-22 19:07:51 +05:30
import mockDiffFile from 'jest/diffs/mock_data/diff_file';
2018-11-08 19:23:39 +05:30
import {
DIFF_VIEW_COOKIE_NAME,
INLINE_DIFF_VIEW_TYPE,
PARALLEL_DIFF_VIEW_TYPE,
2020-01-01 13:55:28 +05:30
DIFFS_PER_PAGE,
2018-11-08 19:23:39 +05:30
} from '~/diffs/constants';
2020-04-22 19:07:51 +05:30
import {
2018-11-20 20:47:30 +05:30
setBaseConfig,
fetchDiffFiles,
2020-01-01 13:55:28 +05:30
fetchDiffFilesBatch,
fetchDiffFilesMeta,
2020-04-08 14:13:33 +05:30
fetchCoverageFiles,
2018-11-20 20:47:30 +05:30
assignDiscussionsToDiff,
removeDiscussionsFromDiff,
startRenderDiffsQueue,
setInlineDiffViewType,
setParallelDiffViewType,
showCommentForm,
cancelCommentForm,
loadMoreLines,
scrollToLineIfNeededInline,
scrollToLineIfNeededParallel,
loadCollapsedDiff,
expandAllFiles,
toggleFileDiscussions,
2018-12-05 23:21:45 +05:30
saveDiffDiscussion,
2019-02-15 15:39:39 +05:30
setHighlightedRow,
2018-12-05 23:21:45 +05:30
toggleTreeOpen,
scrollToFile,
toggleShowTreeList,
2019-02-15 15:39:39 +05:30
renderFileForDiscussionId,
2019-03-02 22:35:43 +05:30
setRenderTreeList,
setShowWhitespace,
2019-07-07 11:18:12 +05:30
setRenderIt,
requestFullDiff,
receiveFullDiffSucess,
receiveFullDiffError,
fetchFullDiff,
toggleFullDiff,
setFileCollapsed,
2019-07-31 22:56:46 +05:30
setExpandedDiffLines,
2019-09-04 21:01:54 +05:30
setSuggestPopoverDismissed,
2018-11-20 20:47:30 +05:30
} from '~/diffs/store/actions';
2019-02-15 15:39:39 +05:30
import eventHub from '~/notes/event_hub';
2018-11-08 19:23:39 +05:30
import * as types from '~/diffs/store/mutation_types';
import axios from '~/lib/utils/axios_utils';
import testAction from '../../helpers/vuex_action_helper';
2020-04-22 19:07:51 +05:30
import * as utils from '~/diffs/store/utils';
import * as commonUtils from '~/lib/utils/common_utils';
import { useLocalStorageSpy } from 'helpers/local_storage_helper';
import createFlash from '~/flash';
jest.mock('~/flash', () => jest.fn());
2018-11-08 19:23:39 +05:30
describe('DiffsStoreActions', () => {
2020-04-22 19:07:51 +05:30
useLocalStorageSpy();
2018-11-20 20:47:30 +05:30
const originalMethods = {
requestAnimationFrame: global.requestAnimationFrame,
requestIdleCallback: global.requestIdleCallback,
};
beforeEach(() => {
2020-04-22 19:07:51 +05:30
jest.spyOn(window.history, 'pushState');
jest.spyOn(commonUtils, 'historyPushState');
jest.spyOn(commonUtils, 'handleLocationHash').mockImplementation(() => null);
jest.spyOn(commonUtils, 'scrollToElement').mockImplementation(() => null);
jest.spyOn(utils, 'convertExpandLines').mockImplementation(() => null);
jest.spyOn(utils, 'idleCallback').mockImplementation(() => null);
2018-11-20 20:47:30 +05:30
['requestAnimationFrame', 'requestIdleCallback'].forEach(method => {
global[method] = cb => {
cb();
};
});
});
afterEach(() => {
['requestAnimationFrame', 'requestIdleCallback'].forEach(method => {
global[method] = originalMethods[method];
});
2020-04-22 19:07:51 +05:30
createFlash.mockClear();
2018-11-20 20:47:30 +05:30
});
2018-11-08 19:23:39 +05:30
describe('setBaseConfig', () => {
it('should set given endpoint and project path', done => {
const endpoint = '/diffs/set/endpoint';
2020-01-01 13:55:28 +05:30
const endpointMetadata = '/diffs/set/endpoint/metadata';
const endpointBatch = '/diffs/set/endpoint/batch';
2020-04-08 14:13:33 +05:30
const endpointCoverage = '/diffs/set/coverage_reports';
2018-11-08 19:23:39 +05:30
const projectPath = '/root/project';
2019-09-04 21:01:54 +05:30
const dismissEndpoint = '/-/user_callouts';
const showSuggestPopover = false;
2020-01-01 13:55:28 +05:30
const useSingleDiffStyle = false;
2018-11-08 19:23:39 +05:30
testAction(
2018-11-20 20:47:30 +05:30
setBaseConfig,
2020-01-01 13:55:28 +05:30
{
endpoint,
endpointBatch,
endpointMetadata,
2020-04-08 14:13:33 +05:30
endpointCoverage,
2020-01-01 13:55:28 +05:30
projectPath,
dismissEndpoint,
showSuggestPopover,
useSingleDiffStyle,
},
{
endpoint: '',
endpointBatch: '',
endpointMetadata: '',
2020-04-08 14:13:33 +05:30
endpointCoverage: '',
2020-01-01 13:55:28 +05:30
projectPath: '',
dismissEndpoint: '',
showSuggestPopover: true,
useSingleDiffStyle: true,
},
2019-09-04 21:01:54 +05:30
[
{
type: types.SET_BASE_CONFIG,
2020-01-01 13:55:28 +05:30
payload: {
endpoint,
endpointMetadata,
endpointBatch,
2020-04-08 14:13:33 +05:30
endpointCoverage,
2020-01-01 13:55:28 +05:30
projectPath,
dismissEndpoint,
showSuggestPopover,
useSingleDiffStyle,
},
2019-09-04 21:01:54 +05:30
},
],
2018-11-08 19:23:39 +05:30
[],
done,
);
});
});
describe('fetchDiffFiles', () => {
it('should fetch diff files', done => {
2020-03-13 15:44:24 +05:30
const endpoint = '/fetch/diff/files?view=inline&w=1';
2018-11-08 19:23:39 +05:30
const mock = new MockAdapter(axios);
const res = { diff_files: 1, merge_request_diffs: [] };
mock.onGet(endpoint).reply(200, res);
testAction(
2018-11-20 20:47:30 +05:30
fetchDiffFiles,
2018-11-08 19:23:39 +05:30
{},
2020-03-13 15:44:24 +05:30
{ endpoint, diffFiles: [], showWhitespace: false, diffViewType: 'inline' },
2018-11-08 19:23:39 +05:30
[
{ type: types.SET_LOADING, payload: true },
{ type: types.SET_LOADING, payload: false },
{ type: types.SET_MERGE_REQUEST_DIFFS, payload: res.merge_request_diffs },
{ type: types.SET_DIFF_DATA, payload: res },
],
[],
() => {
mock.restore();
done();
},
);
2020-03-13 15:44:24 +05:30
fetchDiffFiles({ state: { endpoint }, commit: () => null })
.then(data => {
expect(data).toEqual(res);
done();
})
.catch(done.fail);
2018-11-08 19:23:39 +05:30
});
});
2020-01-01 13:55:28 +05:30
describe('fetchDiffFilesBatch', () => {
it('should fetch batch diff files', done => {
const endpointBatch = '/fetch/diffs_batch';
const mock = new MockAdapter(axios);
const res1 = { diff_files: [], pagination: { next_page: 2 } };
const res2 = { diff_files: [], pagination: {} };
mock
2020-03-13 15:44:24 +05:30
.onGet(endpointBatch, {
params: { page: 1, per_page: DIFFS_PER_PAGE, w: '1', view: 'inline' },
})
.reply(200, res1)
.onGet(endpointBatch, {
params: { page: 2, per_page: DIFFS_PER_PAGE, w: '1', view: 'inline' },
})
2020-01-01 13:55:28 +05:30
.reply(200, res2);
testAction(
fetchDiffFilesBatch,
{},
2020-03-13 15:44:24 +05:30
{ endpointBatch, useSingleDiffStyle: true, diffViewType: 'inline' },
2020-01-01 13:55:28 +05:30
[
{ type: types.SET_BATCH_LOADING, payload: true },
2020-03-13 15:44:24 +05:30
{ type: types.SET_RETRIEVING_BATCHES, payload: true },
2020-01-01 13:55:28 +05:30
{ type: types.SET_DIFF_DATA_BATCH, payload: { diff_files: res1.diff_files } },
{ type: types.SET_BATCH_LOADING, payload: false },
{ type: types.SET_DIFF_DATA_BATCH, payload: { diff_files: [] } },
{ type: types.SET_BATCH_LOADING, payload: false },
2020-03-13 15:44:24 +05:30
{ type: types.SET_RETRIEVING_BATCHES, payload: false },
2020-01-01 13:55:28 +05:30
],
[],
() => {
mock.restore();
done();
},
);
});
});
describe('fetchDiffFilesMeta', () => {
it('should fetch diff meta information', done => {
2020-03-13 15:44:24 +05:30
const endpointMetadata = '/fetch/diffs_meta?view=inline';
2020-01-01 13:55:28 +05:30
const mock = new MockAdapter(axios);
const data = { diff_files: [] };
const res = { data };
mock.onGet(endpointMetadata).reply(200, res);
testAction(
fetchDiffFilesMeta,
{},
{ endpointMetadata },
[
{ type: types.SET_LOADING, payload: true },
{ type: types.SET_LOADING, payload: false },
{ type: types.SET_MERGE_REQUEST_DIFFS, payload: [] },
{ type: types.SET_DIFF_DATA, payload: { data } },
],
[],
() => {
mock.restore();
done();
},
);
});
});
2020-03-13 15:44:24 +05:30
describe('when the single diff view feature flag is off', () => {
describe('fetchDiffFiles', () => {
it('should fetch diff files', done => {
const endpoint = '/fetch/diff/files?w=1';
const mock = new MockAdapter(axios);
const res = { diff_files: 1, merge_request_diffs: [] };
mock.onGet(endpoint).reply(200, res);
testAction(
fetchDiffFiles,
{},
{
endpoint,
diffFiles: [],
showWhitespace: false,
diffViewType: 'inline',
useSingleDiffStyle: false,
},
[
{ type: types.SET_LOADING, payload: true },
{ type: types.SET_LOADING, payload: false },
{ type: types.SET_MERGE_REQUEST_DIFFS, payload: res.merge_request_diffs },
{ type: types.SET_DIFF_DATA, payload: res },
],
[],
() => {
mock.restore();
done();
},
);
fetchDiffFiles({ state: { endpoint }, commit: () => null })
.then(data => {
expect(data).toEqual(res);
done();
})
.catch(done.fail);
});
});
describe('fetchDiffFilesBatch', () => {
it('should fetch batch diff files', done => {
const endpointBatch = '/fetch/diffs_batch';
const mock = new MockAdapter(axios);
const res1 = { diff_files: [], pagination: { next_page: 2 } };
const res2 = { diff_files: [], pagination: {} };
mock
.onGet(endpointBatch, { params: { page: 1, per_page: DIFFS_PER_PAGE, w: '1' } })
.reply(200, res1)
.onGet(endpointBatch, { params: { page: 2, per_page: DIFFS_PER_PAGE, w: '1' } })
.reply(200, res2);
testAction(
fetchDiffFilesBatch,
{},
{ endpointBatch, useSingleDiffStyle: false },
[
{ type: types.SET_BATCH_LOADING, payload: true },
{ type: types.SET_RETRIEVING_BATCHES, payload: true },
{ type: types.SET_DIFF_DATA_BATCH, payload: { diff_files: res1.diff_files } },
{ type: types.SET_BATCH_LOADING, payload: false },
{ type: types.SET_DIFF_DATA_BATCH, payload: { diff_files: [] } },
{ type: types.SET_BATCH_LOADING, payload: false },
{ type: types.SET_RETRIEVING_BATCHES, payload: false },
],
[],
() => {
mock.restore();
done();
},
);
});
});
describe('fetchDiffFilesMeta', () => {
it('should fetch diff meta information', done => {
const endpointMetadata = '/fetch/diffs_meta?';
const mock = new MockAdapter(axios);
const data = { diff_files: [] };
const res = { data };
mock.onGet(endpointMetadata).reply(200, res);
testAction(
fetchDiffFilesMeta,
{},
{ endpointMetadata, useSingleDiffStyle: false },
[
{ type: types.SET_LOADING, payload: true },
{ type: types.SET_LOADING, payload: false },
{ type: types.SET_MERGE_REQUEST_DIFFS, payload: [] },
{ type: types.SET_DIFF_DATA, payload: { data } },
],
[],
() => {
mock.restore();
done();
},
);
});
});
});
2020-04-08 14:13:33 +05:30
describe('fetchCoverageFiles', () => {
let mock;
const endpointCoverage = '/fetch';
beforeEach(() => {
mock = new MockAdapter(axios);
});
afterEach(() => mock.restore());
it('should commit SET_COVERAGE_DATA with received response', done => {
const data = { files: { 'app.js': { '1': 0, '2': 1 } } };
mock.onGet(endpointCoverage).reply(200, { data });
testAction(
fetchCoverageFiles,
{},
{ endpointCoverage },
[{ type: types.SET_COVERAGE_DATA, payload: { data } }],
[],
done,
);
});
it('should show flash on API error', done => {
mock.onGet(endpointCoverage).reply(400);
testAction(fetchCoverageFiles, {}, { endpointCoverage }, [], [], () => {
2020-04-22 19:07:51 +05:30
expect(createFlash).toHaveBeenCalledTimes(1);
expect(createFlash).toHaveBeenCalledWith(expect.stringMatching('Something went wrong'));
2020-04-08 14:13:33 +05:30
done();
});
});
});
2019-02-15 15:39:39 +05:30
describe('setHighlightedRow', () => {
2019-07-07 11:18:12 +05:30
it('should mark currently selected diff and set lineHash and fileHash of highlightedRow', () => {
2019-02-15 15:39:39 +05:30
testAction(setHighlightedRow, 'ABC_123', {}, [
{ type: types.SET_HIGHLIGHTED_ROW, payload: 'ABC_123' },
2019-07-07 11:18:12 +05:30
{ type: types.UPDATE_CURRENT_DIFF_FILE_ID, payload: 'ABC' },
2019-02-15 15:39:39 +05:30
]);
});
});
2018-11-20 20:47:30 +05:30
describe('assignDiscussionsToDiff', () => {
it('should merge discussions into diffs', done => {
2020-03-13 15:44:24 +05:30
window.location.hash = 'ABC_123';
2018-11-20 20:47:30 +05:30
const state = {
diffFiles: [
{
2019-02-15 15:39:39 +05:30
file_hash: 'ABC',
parallel_diff_lines: [
2018-11-20 20:47:30 +05:30
{
left: {
2019-02-15 15:39:39 +05:30
line_code: 'ABC_1_1',
2018-11-20 20:47:30 +05:30
discussions: [],
},
right: {
2019-02-15 15:39:39 +05:30
line_code: 'ABC_1_1',
2018-11-20 20:47:30 +05:30
discussions: [],
},
},
],
2019-02-15 15:39:39 +05:30
highlighted_diff_lines: [
2018-11-20 20:47:30 +05:30
{
2019-02-15 15:39:39 +05:30
line_code: 'ABC_1_1',
2018-11-20 20:47:30 +05:30
discussions: [],
2019-02-15 15:39:39 +05:30
old_line: 5,
new_line: null,
2018-11-20 20:47:30 +05:30
},
],
2019-02-15 15:39:39 +05:30
diff_refs: {
base_sha: 'abc',
head_sha: 'def',
start_sha: 'ghi',
2018-11-20 20:47:30 +05:30
},
2019-02-15 15:39:39 +05:30
new_path: 'file1',
old_path: 'file2',
2018-11-20 20:47:30 +05:30
},
],
};
const diffPosition = {
2019-02-15 15:39:39 +05:30
base_sha: 'abc',
head_sha: 'def',
start_sha: 'ghi',
new_line: null,
new_path: 'file1',
old_line: 5,
old_path: 'file2',
2018-11-20 20:47:30 +05:30
};
const singleDiscussion = {
line_code: 'ABC_1_1',
diff_discussion: {},
diff_file: {
file_hash: 'ABC',
},
2019-02-15 15:39:39 +05:30
file_hash: 'ABC',
2018-11-20 20:47:30 +05:30
resolvable: true,
position: diffPosition,
original_position: diffPosition,
};
2018-12-13 13:39:08 +05:30
const discussions = [singleDiscussion];
2018-11-20 20:47:30 +05:30
testAction(
assignDiscussionsToDiff,
discussions,
state,
[
{
type: types.SET_LINE_DISCUSSIONS_FOR_FILE,
payload: {
2018-12-13 13:39:08 +05:30
discussion: singleDiscussion,
2018-11-20 20:47:30 +05:30
diffPositionByLineCode: {
ABC_1_1: {
2019-02-15 15:39:39 +05:30
base_sha: 'abc',
head_sha: 'def',
start_sha: 'ghi',
new_line: null,
new_path: 'file1',
old_line: 5,
old_path: 'file2',
line_code: 'ABC_1_1',
position_type: 'text',
2020-04-22 19:07:51 +05:30
line_range: null,
2018-11-20 20:47:30 +05:30
},
},
2019-12-04 20:38:33 +05:30
hash: 'ABC_123',
2018-11-20 20:47:30 +05:30
},
},
],
[],
2019-02-15 15:39:39 +05:30
done,
2018-11-20 20:47:30 +05:30
);
});
});
describe('removeDiscussionsFromDiff', () => {
it('should remove discussions from diffs', done => {
const state = {
diffFiles: [
{
2019-02-15 15:39:39 +05:30
file_hash: 'ABC',
parallel_diff_lines: [
2018-11-20 20:47:30 +05:30
{
left: {
2019-02-15 15:39:39 +05:30
line_code: 'ABC_1_1',
2018-11-20 20:47:30 +05:30
discussions: [
{
id: 1,
},
],
},
right: {
2019-02-15 15:39:39 +05:30
line_code: 'ABC_1_1',
2018-11-20 20:47:30 +05:30
discussions: [],
},
},
],
2019-02-15 15:39:39 +05:30
highlighted_diff_lines: [
2018-11-20 20:47:30 +05:30
{
2019-02-15 15:39:39 +05:30
line_code: 'ABC_1_1',
2018-11-20 20:47:30 +05:30
discussions: [],
},
],
},
],
};
const singleDiscussion = {
2018-12-13 13:39:08 +05:30
id: '1',
2019-02-15 15:39:39 +05:30
file_hash: 'ABC',
2018-11-20 20:47:30 +05:30
line_code: 'ABC_1_1',
};
testAction(
removeDiscussionsFromDiff,
singleDiscussion,
state,
[
{
type: types.REMOVE_LINE_DISCUSSIONS_FOR_FILE,
payload: {
2018-12-13 13:39:08 +05:30
id: '1',
2018-11-20 20:47:30 +05:30
fileHash: 'ABC',
lineCode: 'ABC_1_1',
},
},
],
[],
2019-02-15 15:39:39 +05:30
done,
2018-11-20 20:47:30 +05:30
);
});
});
describe('startRenderDiffsQueue', () => {
2018-12-05 23:21:45 +05:30
it('should set all files to RENDER_FILE', () => {
2018-11-20 20:47:30 +05:30
const state = {
diffFiles: [
{
id: 1,
renderIt: false,
2019-07-07 11:18:12 +05:30
viewer: {
collapsed: false,
},
2018-11-20 20:47:30 +05:30
},
{
id: 2,
renderIt: false,
2019-07-07 11:18:12 +05:30
viewer: {
collapsed: false,
},
2018-11-20 20:47:30 +05:30
},
],
};
const pseudoCommit = (commitType, file) => {
expect(commitType).toBe(types.RENDER_FILE);
Object.assign(file, {
renderIt: true,
});
};
2018-12-05 23:21:45 +05:30
startRenderDiffsQueue({ state, commit: pseudoCommit });
2018-11-20 20:47:30 +05:30
2018-12-05 23:21:45 +05:30
expect(state.diffFiles[0].renderIt).toBe(true);
expect(state.diffFiles[1].renderIt).toBe(true);
2018-11-20 20:47:30 +05:30
});
});
2018-11-08 19:23:39 +05:30
describe('setInlineDiffViewType', () => {
it('should set diff view type to inline and also set the cookie properly', done => {
testAction(
2018-11-20 20:47:30 +05:30
setInlineDiffViewType,
2018-11-08 19:23:39 +05:30
null,
{},
[{ type: types.SET_DIFF_VIEW_TYPE, payload: INLINE_DIFF_VIEW_TYPE }],
[],
() => {
2020-04-22 19:07:51 +05:30
setImmediate(() => {
2018-11-08 19:23:39 +05:30
expect(Cookies.get('diff_view')).toEqual(INLINE_DIFF_VIEW_TYPE);
done();
2020-04-22 19:07:51 +05:30
});
2018-11-08 19:23:39 +05:30
},
);
});
});
describe('setParallelDiffViewType', () => {
it('should set diff view type to parallel and also set the cookie properly', done => {
testAction(
2018-11-20 20:47:30 +05:30
setParallelDiffViewType,
2018-11-08 19:23:39 +05:30
null,
{},
[{ type: types.SET_DIFF_VIEW_TYPE, payload: PARALLEL_DIFF_VIEW_TYPE }],
[],
() => {
2020-04-22 19:07:51 +05:30
setImmediate(() => {
2018-11-08 19:23:39 +05:30
expect(Cookies.get(DIFF_VIEW_COOKIE_NAME)).toEqual(PARALLEL_DIFF_VIEW_TYPE);
done();
2020-04-22 19:07:51 +05:30
});
2018-11-08 19:23:39 +05:30
},
);
});
});
describe('showCommentForm', () => {
it('should call mutation to show comment form', done => {
2019-02-15 15:39:39 +05:30
const payload = { lineCode: 'lineCode', fileHash: 'hash' };
2018-11-08 19:23:39 +05:30
testAction(
2018-11-20 20:47:30 +05:30
showCommentForm,
2018-11-08 19:23:39 +05:30
payload,
{},
2019-02-15 15:39:39 +05:30
[{ type: types.TOGGLE_LINE_HAS_FORM, payload: { ...payload, hasForm: true } }],
2018-11-08 19:23:39 +05:30
[],
done,
);
});
});
describe('cancelCommentForm', () => {
it('should call mutation to cancel comment form', done => {
2019-02-15 15:39:39 +05:30
const payload = { lineCode: 'lineCode', fileHash: 'hash' };
2018-11-08 19:23:39 +05:30
testAction(
2018-11-20 20:47:30 +05:30
cancelCommentForm,
2018-11-08 19:23:39 +05:30
payload,
{},
2019-02-15 15:39:39 +05:30
[{ type: types.TOGGLE_LINE_HAS_FORM, payload: { ...payload, hasForm: false } }],
2018-11-08 19:23:39 +05:30
[],
done,
);
});
});
describe('loadMoreLines', () => {
it('should call mutation to show comment form', done => {
const endpoint = '/diffs/load/more/lines';
const params = { since: 6, to: 26 };
const lineNumbers = { oldLineNumber: 3, newLineNumber: 5 };
const fileHash = 'ff9200';
2019-10-12 21:52:04 +05:30
const isExpandDown = false;
const nextLineNumbers = {};
const options = { endpoint, params, lineNumbers, fileHash, isExpandDown, nextLineNumbers };
2018-11-08 19:23:39 +05:30
const mock = new MockAdapter(axios);
const contextLines = { contextLines: [{ lineCode: 6 }] };
mock.onGet(endpoint).reply(200, contextLines);
testAction(
2018-11-20 20:47:30 +05:30
loadMoreLines,
2018-11-08 19:23:39 +05:30
options,
{},
[
{
type: types.ADD_CONTEXT_LINES,
2019-10-12 21:52:04 +05:30
payload: { lineNumbers, contextLines, params, fileHash, isExpandDown, nextLineNumbers },
2018-11-08 19:23:39 +05:30
},
],
[],
() => {
mock.restore();
done();
},
);
});
});
describe('loadCollapsedDiff', () => {
2019-09-04 21:01:54 +05:30
const state = { showWhitespace: true };
2018-11-08 19:23:39 +05:30
it('should fetch data and call mutation with response and the give parameter', done => {
2019-02-15 15:39:39 +05:30
const file = { hash: 123, load_collapsed_diff_url: '/load/collapsed/diff/url' };
2018-11-08 19:23:39 +05:30
const data = { hash: 123, parallelDiffLines: [{ lineCode: 1 }] };
const mock = new MockAdapter(axios);
2020-04-22 19:07:51 +05:30
const commit = jest.fn();
2018-11-08 19:23:39 +05:30
mock.onGet(file.loadCollapsedDiffUrl).reply(200, data);
2019-09-04 21:01:54 +05:30
loadCollapsedDiff({ commit, getters: { commitId: null }, state }, file)
2019-02-15 15:39:39 +05:30
.then(() => {
expect(commit).toHaveBeenCalledWith(types.ADD_COLLAPSED_DIFFS, { file, data });
2018-11-08 19:23:39 +05:30
mock.restore();
done();
2019-02-15 15:39:39 +05:30
})
.catch(done.fail);
});
it('should fetch data without commit ID', () => {
const file = { load_collapsed_diff_url: '/load/collapsed/diff/url' };
const getters = {
commitId: null,
};
2020-04-22 19:07:51 +05:30
jest.spyOn(axios, 'get').mockReturnValue(Promise.resolve({ data: {} }));
2019-02-15 15:39:39 +05:30
2019-09-04 21:01:54 +05:30
loadCollapsedDiff({ commit() {}, getters, state }, file);
2019-02-15 15:39:39 +05:30
expect(axios.get).toHaveBeenCalledWith(file.load_collapsed_diff_url, {
2019-09-04 21:01:54 +05:30
params: { commit_id: null, w: '0' },
2019-02-15 15:39:39 +05:30
});
});
it('should fetch data with commit ID', () => {
const file = { load_collapsed_diff_url: '/load/collapsed/diff/url' };
const getters = {
commitId: '123',
};
2020-04-22 19:07:51 +05:30
jest.spyOn(axios, 'get').mockReturnValue(Promise.resolve({ data: {} }));
2019-02-15 15:39:39 +05:30
2019-09-04 21:01:54 +05:30
loadCollapsedDiff({ commit() {}, getters, state }, file);
2019-02-15 15:39:39 +05:30
expect(axios.get).toHaveBeenCalledWith(file.load_collapsed_diff_url, {
2019-09-04 21:01:54 +05:30
params: { commit_id: '123', w: '0' },
2019-02-15 15:39:39 +05:30
});
2018-11-08 19:23:39 +05:30
});
});
describe('expandAllFiles', () => {
it('should change the collapsed prop from the diffFiles', done => {
testAction(
2018-11-20 20:47:30 +05:30
expandAllFiles,
2018-11-08 19:23:39 +05:30
null,
{},
[
{
type: types.EXPAND_ALL_FILES,
},
],
[],
done,
);
});
});
describe('toggleFileDiscussions', () => {
it('should dispatch collapseDiscussion when all discussions are expanded', () => {
const getters = {
2020-04-22 19:07:51 +05:30
getDiffFileDiscussions: jest.fn(() => [{ id: 1 }]),
diffHasAllExpandedDiscussions: jest.fn(() => true),
diffHasAllCollapsedDiscussions: jest.fn(() => false),
2018-11-08 19:23:39 +05:30
};
2020-04-22 19:07:51 +05:30
const dispatch = jest.fn();
2018-11-08 19:23:39 +05:30
2018-11-20 20:47:30 +05:30
toggleFileDiscussions({ getters, dispatch });
2018-11-08 19:23:39 +05:30
2018-11-20 20:47:30 +05:30
expect(dispatch).toHaveBeenCalledWith(
'collapseDiscussion',
{ discussionId: 1 },
{ root: true },
);
2018-11-08 19:23:39 +05:30
});
it('should dispatch expandDiscussion when all discussions are collapsed', () => {
const getters = {
2020-04-22 19:07:51 +05:30
getDiffFileDiscussions: jest.fn(() => [{ id: 1 }]),
diffHasAllExpandedDiscussions: jest.fn(() => false),
diffHasAllCollapsedDiscussions: jest.fn(() => true),
2018-11-08 19:23:39 +05:30
};
2020-04-22 19:07:51 +05:30
const dispatch = jest.fn();
2018-11-08 19:23:39 +05:30
2018-11-20 20:47:30 +05:30
toggleFileDiscussions({ getters, dispatch });
2018-11-08 19:23:39 +05:30
2018-11-20 20:47:30 +05:30
expect(dispatch).toHaveBeenCalledWith(
'expandDiscussion',
{ discussionId: 1 },
{ root: true },
);
2018-11-08 19:23:39 +05:30
});
it('should dispatch expandDiscussion when some discussions are collapsed and others are expanded for the collapsed discussion', () => {
const getters = {
2020-04-22 19:07:51 +05:30
getDiffFileDiscussions: jest.fn(() => [{ expanded: false, id: 1 }]),
diffHasAllExpandedDiscussions: jest.fn(() => false),
diffHasAllCollapsedDiscussions: jest.fn(() => false),
2018-11-08 19:23:39 +05:30
};
2020-04-22 19:07:51 +05:30
const dispatch = jest.fn();
2018-11-08 19:23:39 +05:30
2018-11-20 20:47:30 +05:30
toggleFileDiscussions({ getters, dispatch });
expect(dispatch).toHaveBeenCalledWith(
'expandDiscussion',
{ discussionId: 1 },
{ root: true },
);
});
});
describe('scrollToLineIfNeededInline', () => {
const lineMock = {
2019-02-15 15:39:39 +05:30
line_code: 'ABC_123',
2018-11-20 20:47:30 +05:30
};
it('should not call handleLocationHash when there is not hash', () => {
window.location.hash = '';
scrollToLineIfNeededInline({}, lineMock);
2020-04-22 19:07:51 +05:30
expect(commonUtils.handleLocationHash).not.toHaveBeenCalled();
2018-11-20 20:47:30 +05:30
});
it('should not call handleLocationHash when the hash does not match any line', () => {
window.location.hash = 'XYZ_456';
scrollToLineIfNeededInline({}, lineMock);
2020-04-22 19:07:51 +05:30
expect(commonUtils.handleLocationHash).not.toHaveBeenCalled();
2018-11-20 20:47:30 +05:30
});
it('should call handleLocationHash only when the hash matches a line', () => {
window.location.hash = 'ABC_123';
scrollToLineIfNeededInline(
{},
{
lineCode: 'ABC_456',
},
);
scrollToLineIfNeededInline({}, lineMock);
scrollToLineIfNeededInline(
{},
{
lineCode: 'XYZ_456',
},
);
2020-04-22 19:07:51 +05:30
expect(commonUtils.handleLocationHash).toHaveBeenCalled();
expect(commonUtils.handleLocationHash).toHaveBeenCalledTimes(1);
2018-11-20 20:47:30 +05:30
});
});
describe('scrollToLineIfNeededParallel', () => {
const lineMock = {
left: null,
right: {
2019-02-15 15:39:39 +05:30
line_code: 'ABC_123',
2018-11-20 20:47:30 +05:30
},
};
it('should not call handleLocationHash when there is not hash', () => {
window.location.hash = '';
scrollToLineIfNeededParallel({}, lineMock);
2020-04-22 19:07:51 +05:30
expect(commonUtils.handleLocationHash).not.toHaveBeenCalled();
2018-11-20 20:47:30 +05:30
});
it('should not call handleLocationHash when the hash does not match any line', () => {
window.location.hash = 'XYZ_456';
scrollToLineIfNeededParallel({}, lineMock);
2020-04-22 19:07:51 +05:30
expect(commonUtils.handleLocationHash).not.toHaveBeenCalled();
2018-11-20 20:47:30 +05:30
});
it('should call handleLocationHash only when the hash matches a line', () => {
window.location.hash = 'ABC_123';
scrollToLineIfNeededParallel(
{},
{
left: null,
right: {
lineCode: 'ABC_456',
},
},
);
scrollToLineIfNeededParallel({}, lineMock);
scrollToLineIfNeededParallel(
{},
{
left: null,
right: {
lineCode: 'XYZ_456',
},
},
);
2018-11-08 19:23:39 +05:30
2020-04-22 19:07:51 +05:30
expect(commonUtils.handleLocationHash).toHaveBeenCalled();
expect(commonUtils.handleLocationHash).toHaveBeenCalledTimes(1);
2018-11-08 19:23:39 +05:30
});
});
2018-12-05 23:21:45 +05:30
describe('saveDiffDiscussion', () => {
it('dispatches actions', done => {
2019-02-15 15:39:39 +05:30
const commitId = 'something';
const formData = {
diffFile: { ...mockDiffFile },
noteableData: {},
};
const note = {};
const state = {
commit: {
id: commitId,
},
};
2020-04-22 19:07:51 +05:30
const dispatch = jest.fn(name => {
2018-12-05 23:21:45 +05:30
switch (name) {
case 'saveNote':
return Promise.resolve({
discussion: 'test',
});
case 'updateDiscussion':
return Promise.resolve('discussion');
default:
return Promise.resolve({});
}
});
2019-02-15 15:39:39 +05:30
saveDiffDiscussion({ state, dispatch }, { note, formData })
2018-12-05 23:21:45 +05:30
.then(() => {
2020-04-22 19:07:51 +05:30
expect(dispatch).toHaveBeenCalledTimes(5);
expect(dispatch).toHaveBeenNthCalledWith(1, 'saveNote', expect.any(Object), {
root: true,
});
2019-02-15 15:39:39 +05:30
2020-04-22 19:07:51 +05:30
const postData = dispatch.mock.calls[0][1];
2019-02-15 15:39:39 +05:30
expect(postData.data.note.commit_id).toBe(commitId);
2020-04-22 19:07:51 +05:30
expect(dispatch).toHaveBeenNthCalledWith(2, 'updateDiscussion', 'test', { root: true });
expect(dispatch).toHaveBeenNthCalledWith(3, 'assignDiscussionsToDiff', ['discussion']);
2018-12-05 23:21:45 +05:30
})
.then(done)
.catch(done.fail);
});
});
describe('toggleTreeOpen', () => {
it('commits TOGGLE_FOLDER_OPEN', done => {
testAction(
toggleTreeOpen,
'path',
{},
[{ type: types.TOGGLE_FOLDER_OPEN, payload: 'path' }],
[],
done,
);
});
});
describe('scrollToFile', () => {
let commit;
beforeEach(() => {
2020-04-22 19:07:51 +05:30
commit = jest.fn();
2018-12-05 23:21:45 +05:30
});
it('updates location hash', () => {
const state = {
treeEntries: {
path: {
fileHash: 'test',
},
},
};
scrollToFile({ state, commit }, 'path');
expect(document.location.hash).toBe('#test');
});
it('commits UPDATE_CURRENT_DIFF_FILE_ID', () => {
const state = {
treeEntries: {
path: {
fileHash: 'test',
},
},
};
scrollToFile({ state, commit }, 'path');
expect(commit).toHaveBeenCalledWith(types.UPDATE_CURRENT_DIFF_FILE_ID, 'test');
});
});
describe('toggleShowTreeList', () => {
it('commits toggle', done => {
testAction(toggleShowTreeList, null, {}, [{ type: types.TOGGLE_SHOW_TREE_LIST }], [], done);
});
it('updates localStorage', () => {
2020-04-22 19:07:51 +05:30
jest.spyOn(localStorage, 'setItem').mockImplementation(() => {});
2018-12-05 23:21:45 +05:30
toggleShowTreeList({ commit() {}, state: { showTreeList: true } });
expect(localStorage.setItem).toHaveBeenCalledWith('mr_tree_show', true);
});
2019-07-07 11:18:12 +05:30
it('does not update localStorage', () => {
2020-04-22 19:07:51 +05:30
jest.spyOn(localStorage, 'setItem').mockImplementation(() => {});
2019-07-07 11:18:12 +05:30
toggleShowTreeList({ commit() {}, state: { showTreeList: true } }, false);
expect(localStorage.setItem).not.toHaveBeenCalled();
});
2018-12-05 23:21:45 +05:30
});
2019-02-15 15:39:39 +05:30
describe('renderFileForDiscussionId', () => {
const rootState = {
notes: {
discussions: [
{
id: '123',
diff_file: {
file_hash: 'HASH',
},
},
{
id: '456',
diff_file: {
file_hash: 'HASH',
},
},
],
},
};
let commit;
let $emit;
const state = ({ collapsed, renderIt }) => ({
diffFiles: [
{
file_hash: 'HASH',
2019-07-07 11:18:12 +05:30
viewer: {
collapsed,
},
2019-02-15 15:39:39 +05:30
renderIt,
},
],
});
beforeEach(() => {
2020-04-22 19:07:51 +05:30
commit = jest.fn();
$emit = jest.spyOn(eventHub, '$emit');
2019-02-15 15:39:39 +05:30
});
it('renders and expands file for the given discussion id', () => {
const localState = state({ collapsed: true, renderIt: false });
renderFileForDiscussionId({ rootState, state: localState, commit }, '123');
expect(commit).toHaveBeenCalledWith('RENDER_FILE', localState.diffFiles[0]);
expect($emit).toHaveBeenCalledTimes(1);
2020-04-22 19:07:51 +05:30
expect(commonUtils.scrollToElement).toHaveBeenCalledTimes(1);
2019-02-15 15:39:39 +05:30
});
it('jumps to discussion on already rendered and expanded file', () => {
const localState = state({ collapsed: false, renderIt: true });
renderFileForDiscussionId({ rootState, state: localState, commit }, '123');
expect(commit).not.toHaveBeenCalled();
expect($emit).toHaveBeenCalledTimes(1);
2020-04-22 19:07:51 +05:30
expect(commonUtils.scrollToElement).not.toHaveBeenCalled();
2019-02-15 15:39:39 +05:30
});
});
2019-03-02 22:35:43 +05:30
describe('setRenderTreeList', () => {
it('commits SET_RENDER_TREE_LIST', done => {
testAction(
setRenderTreeList,
true,
{},
[{ type: types.SET_RENDER_TREE_LIST, payload: true }],
[],
done,
);
});
it('sets localStorage', () => {
setRenderTreeList({ commit() {} }, true);
expect(localStorage.setItem).toHaveBeenCalledWith('mr_diff_tree_list', true);
});
});
describe('setShowWhitespace', () => {
2019-09-04 21:01:54 +05:30
beforeEach(() => {
2020-04-22 19:07:51 +05:30
jest.spyOn(eventHub, '$emit').mockImplementation();
2019-09-04 21:01:54 +05:30
});
2019-03-02 22:35:43 +05:30
it('commits SET_SHOW_WHITESPACE', done => {
testAction(
setShowWhitespace,
{ showWhitespace: true },
{},
[{ type: types.SET_SHOW_WHITESPACE, payload: true }],
[],
done,
);
});
it('sets localStorage', () => {
setShowWhitespace({ commit() {} }, { showWhitespace: true });
expect(localStorage.setItem).toHaveBeenCalledWith('mr_show_whitespace', true);
});
it('calls history pushState', () => {
setShowWhitespace({ commit() {} }, { showWhitespace: true, pushState: true });
expect(window.history.pushState).toHaveBeenCalled();
});
2019-09-04 21:01:54 +05:30
it('calls history pushState with merged params', () => {
2020-04-22 19:07:51 +05:30
window.history.pushState({}, '', '?test=1');
2019-09-04 21:01:54 +05:30
setShowWhitespace({ commit() {} }, { showWhitespace: true, pushState: true });
2020-04-22 19:07:51 +05:30
expect(
window.history.pushState.mock.calls[window.history.pushState.mock.calls.length - 1][2],
).toMatch(/(.*)\?test=1&w=0/);
2019-09-04 21:01:54 +05:30
2020-04-22 19:07:51 +05:30
window.history.pushState({}, '', '?');
2019-09-04 21:01:54 +05:30
});
it('emits eventHub event', () => {
setShowWhitespace({ commit() {} }, { showWhitespace: true, pushState: true });
expect(eventHub.$emit).toHaveBeenCalledWith('refetchDiffData');
});
2019-03-02 22:35:43 +05:30
});
2019-07-07 11:18:12 +05:30
describe('setRenderIt', () => {
it('commits RENDER_FILE', done => {
testAction(setRenderIt, 'file', {}, [{ type: types.RENDER_FILE, payload: 'file' }], [], done);
});
});
describe('requestFullDiff', () => {
it('commits REQUEST_FULL_DIFF', done => {
testAction(
requestFullDiff,
'file',
{},
[{ type: types.REQUEST_FULL_DIFF, payload: 'file' }],
[],
done,
);
});
});
describe('receiveFullDiffSucess', () => {
it('commits REQUEST_FULL_DIFF', done => {
testAction(
receiveFullDiffSucess,
2019-07-31 22:56:46 +05:30
{ filePath: 'test' },
2019-07-07 11:18:12 +05:30
{},
2019-07-31 22:56:46 +05:30
[{ type: types.RECEIVE_FULL_DIFF_SUCCESS, payload: { filePath: 'test' } }],
2019-07-07 11:18:12 +05:30
[],
done,
);
});
});
describe('receiveFullDiffError', () => {
it('commits REQUEST_FULL_DIFF', done => {
testAction(
receiveFullDiffError,
'file',
{},
[{ type: types.RECEIVE_FULL_DIFF_ERROR, payload: 'file' }],
[],
done,
);
});
});
describe('fetchFullDiff', () => {
let mock;
beforeEach(() => {
mock = new MockAdapter(axios);
});
afterEach(() => {
mock.restore();
});
describe('success', () => {
beforeEach(() => {
mock.onGet(`${gl.TEST_HOST}/context`).replyOnce(200, ['test']);
});
it('dispatches receiveFullDiffSucess', done => {
2019-07-31 22:56:46 +05:30
const file = {
context_lines_path: `${gl.TEST_HOST}/context`,
file_path: 'test',
file_hash: 'test',
};
2019-07-07 11:18:12 +05:30
testAction(
fetchFullDiff,
2019-07-31 22:56:46 +05:30
file,
2019-07-07 11:18:12 +05:30
null,
[],
2019-07-31 22:56:46 +05:30
[
{ type: 'receiveFullDiffSucess', payload: { filePath: 'test' } },
{ type: 'setExpandedDiffLines', payload: { file, data: ['test'] } },
],
2019-07-07 11:18:12 +05:30
done,
);
});
});
describe('error', () => {
beforeEach(() => {
mock.onGet(`${gl.TEST_HOST}/context`).replyOnce(500);
});
it('dispatches receiveFullDiffError', done => {
testAction(
fetchFullDiff,
{ context_lines_path: `${gl.TEST_HOST}/context`, file_path: 'test', file_hash: 'test' },
null,
[],
[{ type: 'receiveFullDiffError', payload: 'test' }],
done,
);
});
});
});
describe('toggleFullDiff', () => {
let state;
beforeEach(() => {
state = {
diffFiles: [{ file_path: 'test', isShowingFullFile: false }],
};
});
it('dispatches fetchFullDiff when file is not expanded', done => {
testAction(
toggleFullDiff,
'test',
state,
[],
[
{ type: 'requestFullDiff', payload: 'test' },
{ type: 'fetchFullDiff', payload: state.diffFiles[0] },
],
done,
);
});
});
describe('setFileCollapsed', () => {
it('commits SET_FILE_COLLAPSED', done => {
testAction(
setFileCollapsed,
{ filePath: 'test', collapsed: true },
null,
[{ type: types.SET_FILE_COLLAPSED, payload: { filePath: 'test', collapsed: true } }],
[],
done,
);
});
});
2019-07-31 22:56:46 +05:30
describe('setExpandedDiffLines', () => {
beforeEach(() => {
2020-04-22 19:07:51 +05:30
utils.idleCallback.mockImplementation(cb => {
2019-07-31 22:56:46 +05:30
cb({ timeRemaining: () => 50 });
});
});
it('commits SET_CURRENT_VIEW_DIFF_FILE_LINES when lines less than MAX_RENDERING_DIFF_LINES', done => {
2020-04-22 19:07:51 +05:30
utils.convertExpandLines.mockImplementation(() => ['test']);
2019-07-31 22:56:46 +05:30
testAction(
setExpandedDiffLines,
{ file: { file_path: 'path' }, data: [] },
{ diffViewType: 'inline' },
[
{
type: 'SET_HIDDEN_VIEW_DIFF_FILE_LINES',
payload: { filePath: 'path', lines: ['test'] },
},
{
type: 'SET_CURRENT_VIEW_DIFF_FILE_LINES',
payload: { filePath: 'path', lines: ['test'] },
},
],
[],
done,
);
});
it('commits ADD_CURRENT_VIEW_DIFF_FILE_LINES when lines more than MAX_RENDERING_DIFF_LINES', done => {
const lines = new Array(501).fill().map((_, i) => `line-${i}`);
2020-04-22 19:07:51 +05:30
utils.convertExpandLines.mockReturnValue(lines);
2019-07-31 22:56:46 +05:30
testAction(
setExpandedDiffLines,
{ file: { file_path: 'path' }, data: [] },
{ diffViewType: 'inline' },
[
{
type: 'SET_HIDDEN_VIEW_DIFF_FILE_LINES',
payload: { filePath: 'path', lines },
},
{
type: 'SET_CURRENT_VIEW_DIFF_FILE_LINES',
payload: { filePath: 'path', lines: lines.slice(0, 200) },
},
{ type: 'TOGGLE_DIFF_FILE_RENDERING_MORE', payload: 'path' },
...new Array(301).fill().map((_, i) => ({
type: 'ADD_CURRENT_VIEW_DIFF_FILE_LINES',
payload: { filePath: 'path', line: `line-${i + 200}` },
})),
{ type: 'TOGGLE_DIFF_FILE_RENDERING_MORE', payload: 'path' },
],
[],
done,
);
});
});
2019-09-04 21:01:54 +05:30
describe('setSuggestPopoverDismissed', () => {
it('commits SET_SHOW_SUGGEST_POPOVER', done => {
const state = { dismissEndpoint: `${gl.TEST_HOST}/-/user_callouts` };
const mock = new MockAdapter(axios);
mock.onPost(state.dismissEndpoint).reply(200, {});
2020-04-22 19:07:51 +05:30
jest.spyOn(axios, 'post');
2019-09-04 21:01:54 +05:30
testAction(
setSuggestPopoverDismissed,
null,
state,
[{ type: types.SET_SHOW_SUGGEST_POPOVER }],
[],
() => {
expect(axios.post).toHaveBeenCalledWith(state.dismissEndpoint, {
feature_name: 'suggest_popover_dismissed',
});
mock.restore();
done();
},
);
});
});
2018-11-08 19:23:39 +05:30
});