Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-06-18 14:18:50 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2020-06-18 14:18:50 +0300
commit8c7f4e9d5f36cff46365a7f8c4b9c21578c1e781 (patch)
treea77e7fe7a93de11213032ed4ab1f33a3db51b738 /spec/frontend/diffs
parent00b35af3db1abfe813a778f643dad221aad51fca (diff)
Add latest changes from gitlab-org/gitlab@13-1-stable-ee
Diffstat (limited to 'spec/frontend/diffs')
-rw-r--r--spec/frontend/diffs/components/diff_file_spec.js2
-rw-r--r--spec/frontend/diffs/components/diff_line_note_form_spec.js14
-rw-r--r--spec/frontend/diffs/components/inline_diff_view_spec.js2
-rw-r--r--spec/frontend/diffs/components/parallel_diff_view_spec.js2
-rw-r--r--spec/frontend/diffs/mock_data/diff_file.js1
-rw-r--r--spec/frontend/diffs/mock_data/diff_metadata.js58
-rw-r--r--spec/frontend/diffs/store/actions_spec.js228
-rw-r--r--spec/frontend/diffs/store/utils_spec.js243
-rw-r--r--spec/frontend/diffs/utils/uuids_spec.js92
9 files changed, 454 insertions, 188 deletions
diff --git a/spec/frontend/diffs/components/diff_file_spec.js b/spec/frontend/diffs/components/diff_file_spec.js
index d0ba71fce47..71e975f2409 100644
--- a/spec/frontend/diffs/components/diff_file_spec.js
+++ b/spec/frontend/diffs/components/diff_file_spec.js
@@ -1,5 +1,5 @@
import Vue from 'vue';
-import { createStore } from 'ee_else_ce/mr_notes/stores';
+import { createStore } from '~/mr_notes/stores';
import { createComponentWithStore } from 'helpers/vue_mount_component_helper';
import { mockTracking, triggerEvent } from 'helpers/tracking_helper';
import DiffFileComponent from '~/diffs/components/diff_file.vue';
diff --git a/spec/frontend/diffs/components/diff_line_note_form_spec.js b/spec/frontend/diffs/components/diff_line_note_form_spec.js
index 3e0acd0dace..623df8bd55e 100644
--- a/spec/frontend/diffs/components/diff_line_note_form_spec.js
+++ b/spec/frontend/diffs/components/diff_line_note_form_spec.js
@@ -77,12 +77,24 @@ describe('DiffLineNoteForm', () => {
.spyOn(wrapper.vm, 'saveDiffDiscussion')
.mockReturnValue(Promise.resolve());
+ const lineRange = {
+ start_line_code: wrapper.vm.commentLineStart.lineCode,
+ start_line_type: wrapper.vm.commentLineStart.type,
+ end_line_code: wrapper.vm.line.line_code,
+ end_line_type: wrapper.vm.line.type,
+ };
+
+ const formData = {
+ ...wrapper.vm.formData,
+ lineRange,
+ };
+
wrapper.vm
.handleSaveNote('note body')
.then(() => {
expect(saveDiffDiscussionSpy).toHaveBeenCalledWith({
note: 'note body',
- formData: wrapper.vm.formData,
+ formData,
});
})
.then(done)
diff --git a/spec/frontend/diffs/components/inline_diff_view_spec.js b/spec/frontend/diffs/components/inline_diff_view_spec.js
index 9b0cf6a84d9..eeef8e5a7b0 100644
--- a/spec/frontend/diffs/components/inline_diff_view_spec.js
+++ b/spec/frontend/diffs/components/inline_diff_view_spec.js
@@ -1,6 +1,6 @@
import Vue from 'vue';
import '~/behaviors/markdown/render_gfm';
-import { createStore } from 'ee_else_ce/mr_notes/stores';
+import { createStore } from '~/mr_notes/stores';
import { createComponentWithStore } from 'helpers/vue_mount_component_helper';
import InlineDiffView from '~/diffs/components/inline_diff_view.vue';
import diffFileMockData from '../mock_data/diff_file';
diff --git a/spec/frontend/diffs/components/parallel_diff_view_spec.js b/spec/frontend/diffs/components/parallel_diff_view_spec.js
index 03cf1b72b62..30231f0ba71 100644
--- a/spec/frontend/diffs/components/parallel_diff_view_spec.js
+++ b/spec/frontend/diffs/components/parallel_diff_view_spec.js
@@ -1,5 +1,5 @@
import Vue from 'vue';
-import { createStore } from 'ee_else_ce/mr_notes/stores';
+import { createStore } from '~/mr_notes/stores';
import { createComponentWithStore } from 'helpers/vue_mount_component_helper';
import ParallelDiffView from '~/diffs/components/parallel_diff_view.vue';
import * as constants from '~/diffs/constants';
diff --git a/spec/frontend/diffs/mock_data/diff_file.js b/spec/frontend/diffs/mock_data/diff_file.js
index 27428197c1c..e4b2fdf6ede 100644
--- a/spec/frontend/diffs/mock_data/diff_file.js
+++ b/spec/frontend/diffs/mock_data/diff_file.js
@@ -13,6 +13,7 @@ export default {
blob_name: 'CHANGELOG',
blob_icon: '<i aria-hidden="true" data-hidden="true" class="fa fa-file-text-o fa-fw"></i>',
file_hash: '1c497fbb3a46b78edf04cc2a2fa33f67e3ffbe2a',
+ file_identifier_hash: '928f8286952bda02d674b692addcbe077084663a',
file_path: 'CHANGELOG',
new_file: false,
deleted_file: false,
diff --git a/spec/frontend/diffs/mock_data/diff_metadata.js b/spec/frontend/diffs/mock_data/diff_metadata.js
new file mode 100644
index 00000000000..b73b29e4bc8
--- /dev/null
+++ b/spec/frontend/diffs/mock_data/diff_metadata.js
@@ -0,0 +1,58 @@
+/* eslint-disable import/prefer-default-export */
+/* https://gitlab.com/gitlab-org/frontend/rfcs/-/issues/20 */
+
+export const diffMetadata = {
+ real_size: '1',
+ size: 1,
+ branch_name: 'update-changelog',
+ source_branch_exists: true,
+ target_branch_name: 'master',
+ commit: null,
+ context_commits: null,
+ merge_request_diff: {
+ version_index: null,
+ created_at: '2019-11-07T06:48:35.202Z',
+ commits_count: 1,
+ latest: true,
+ short_commit_sha: 'eb227b3e',
+ base_version_path: '/gitlab-org/gitlab-test/-/merge_requests/4/diffs?diff_id=4',
+ head_version_path: '/gitlab-org/gitlab-test/-/merge_requests/4/diffs?diff_head=true',
+ version_path: '/gitlab-org/gitlab-test/-/merge_requests/4/diffs?diff_id=4',
+ compare_path:
+ '/gitlab-org/gitlab-test/-/merge_requests/4/diffs?diff_id=4\u0026start_sha=eb227b3e214624708c474bdab7bde7afc17cefcc',
+ },
+ start_version: null,
+ latest_diff: true,
+ latest_version_path: '/gitlab-org/gitlab-test/-/merge_requests/4/diffs',
+ added_lines: 2,
+ removed_lines: 0,
+ render_overflow_warning: false,
+ email_patch_path: '/gitlab-org/gitlab-test/-/merge_requests/4.patch',
+ plain_diff_path: '/gitlab-org/gitlab-test/-/merge_requests/4.diff',
+ merge_request_diffs: [
+ {
+ version_index: null,
+ created_at: '2019-11-07T06:48:35.202Z',
+ commits_count: 1,
+ latest: true,
+ short_commit_sha: 'eb227b3e',
+ base_version_path: '/gitlab-org/gitlab-test/-/merge_requests/4/diffs?diff_id=4',
+ head_version_path: '/gitlab-org/gitlab-test/-/merge_requests/4/diffs?diff_head=true',
+ version_path: '/gitlab-org/gitlab-test/-/merge_requests/4/diffs?diff_id=4',
+ compare_path:
+ '/gitlab-org/gitlab-test/-/merge_requests/4/diffs?diff_id=4\u0026start_sha=eb227b3e214624708c474bdab7bde7afc17cefcc',
+ },
+ ],
+ diff_files: [
+ {
+ added_lines: 2,
+ removed_lines: 0,
+ new_path: 'CHANGELOG',
+ old_path: 'CHANGELOG',
+ new_file: false,
+ deleted_file: false,
+ file_identifier_hash: '928f8286952bda02d674b692addcbe077084663a',
+ file_hash: '1c497fbb3a46b78edf04cc2a2fa33f67e3ffbe2a',
+ },
+ ],
+};
diff --git a/spec/frontend/diffs/store/actions_spec.js b/spec/frontend/diffs/store/actions_spec.js
index 3fba661da44..7d79dcfbfe3 100644
--- a/spec/frontend/diffs/store/actions_spec.js
+++ b/spec/frontend/diffs/store/actions_spec.js
@@ -35,8 +35,6 @@ import {
setRenderTreeList,
setShowWhitespace,
setRenderIt,
- requestFullDiff,
- receiveFullDiffSucess,
receiveFullDiffError,
fetchFullDiff,
toggleFullDiff,
@@ -53,7 +51,9 @@ import axios from '~/lib/utils/axios_utils';
import testAction from '../../helpers/vuex_action_helper';
import * as utils from '~/diffs/store/utils';
import * as commonUtils from '~/lib/utils/common_utils';
+import { mergeUrlParams } from '~/lib/utils/url_utility';
import { useLocalStorageSpy } from 'helpers/local_storage_helper';
+import { diffMetadata } from '../mock_data/diff_metadata';
import createFlash from '~/flash';
jest.mock('~/flash', () => jest.fn());
@@ -175,19 +175,44 @@ describe('DiffsStoreActions', () => {
});
describe('fetchDiffFilesBatch', () => {
+ let mock;
+
+ beforeEach(() => {
+ mock = new MockAdapter(axios);
+ });
+
+ afterEach(() => {
+ mock.restore();
+ });
+
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', view: 'inline' },
- })
+ .onGet(
+ mergeUrlParams(
+ {
+ per_page: DIFFS_PER_PAGE,
+ w: '1',
+ view: 'inline',
+ page: 1,
+ },
+ endpointBatch,
+ ),
+ )
.reply(200, res1)
- .onGet(endpointBatch, {
- params: { page: 2, per_page: DIFFS_PER_PAGE, w: '1', view: 'inline' },
- })
+ .onGet(
+ mergeUrlParams(
+ {
+ per_page: DIFFS_PER_PAGE,
+ w: '1',
+ view: 'inline',
+ page: 2,
+ },
+ endpointBatch,
+ ),
+ )
.reply(200, res2);
testAction(
@@ -204,22 +229,50 @@ describe('DiffsStoreActions', () => {
{ type: types.SET_RETRIEVING_BATCHES, payload: false },
],
[],
- () => {
- mock.restore();
- done();
- },
+ done,
);
});
+
+ it.each`
+ viewStyle | otherView
+ ${'inline'} | ${'parallel'}
+ ${'parallel'} | ${'inline'}
+ `(
+ 'should make a request with the view parameter "$viewStyle" when the batchEndpoint already contains "$otherView"',
+ ({ viewStyle, otherView }) => {
+ const endpointBatch = '/fetch/diffs_batch';
+
+ fetchDiffFilesBatch({
+ commit: () => {},
+ state: {
+ endpointBatch: `${endpointBatch}?view=${otherView}`,
+ useSingleDiffStyle: true,
+ diffViewType: viewStyle,
+ },
+ })
+ .then(() => {
+ expect(mock.history.get[0].url).toContain(`view=${viewStyle}`);
+ expect(mock.history.get[0].url).not.toContain(`view=${otherView}`);
+ })
+ .catch(() => {});
+ },
+ );
});
describe('fetchDiffFilesMeta', () => {
- it('should fetch diff meta information', done => {
- const endpointMetadata = '/fetch/diffs_meta?view=inline';
- const mock = new MockAdapter(axios);
- const data = { diff_files: [] };
- const res = { data };
- mock.onGet(endpointMetadata).reply(200, res);
+ const endpointMetadata = '/fetch/diffs_metadata.json?view=inline';
+ const noFilesData = { ...diffMetadata };
+ let mock;
+
+ beforeEach(() => {
+ mock = new MockAdapter(axios);
+
+ delete noFilesData.diff_files;
+
+ mock.onGet(endpointMetadata).reply(200, diffMetadata);
+ });
+ it('should fetch diff meta information', done => {
testAction(
fetchDiffFilesMeta,
{},
@@ -227,8 +280,8 @@ describe('DiffsStoreActions', () => {
[
{ 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 } },
+ { type: types.SET_MERGE_REQUEST_DIFFS, payload: diffMetadata.merge_request_diffs },
+ { type: types.SET_DIFF_DATA, payload: noFilesData },
],
[],
() => {
@@ -280,15 +333,24 @@ describe('DiffsStoreActions', () => {
});
describe('fetchDiffFilesBatch', () => {
+ let mock;
+
+ beforeEach(() => {
+ mock = new MockAdapter(axios);
+ });
+
+ afterEach(() => {
+ mock.restore();
+ });
+
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' } })
+ .onGet(mergeUrlParams({ per_page: DIFFS_PER_PAGE, w: '1', page: 1 }, endpointBatch))
.reply(200, res1)
- .onGet(endpointBatch, { params: { page: 2, per_page: DIFFS_PER_PAGE, w: '1' } })
+ .onGet(mergeUrlParams({ per_page: DIFFS_PER_PAGE, w: '1', page: 2 }, endpointBatch))
.reply(200, res2);
testAction(
@@ -305,22 +367,48 @@ describe('DiffsStoreActions', () => {
{ type: types.SET_RETRIEVING_BATCHES, payload: false },
],
[],
- () => {
- mock.restore();
- done();
- },
+ done,
);
});
+
+ it.each`
+ querystrings | requestUrl
+ ${'?view=parallel'} | ${'/fetch/diffs_batch?view=parallel'}
+ ${'?view=inline'} | ${'/fetch/diffs_batch?view=inline'}
+ ${''} | ${'/fetch/diffs_batch'}
+ `(
+ 'should use the endpoint $requestUrl if the endpointBatch in state includes `$querystrings` as a querystring',
+ ({ querystrings, requestUrl }) => {
+ const endpointBatch = '/fetch/diffs_batch';
+
+ fetchDiffFilesBatch({
+ commit: () => {},
+ state: {
+ endpointBatch: `${endpointBatch}${querystrings}`,
+ diffViewType: 'inline',
+ },
+ })
+ .then(() => {
+ expect(mock.history.get[0].url).toEqual(requestUrl);
+ })
+ .catch(() => {});
+ },
+ );
});
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);
+ const endpointMetadata = '/fetch/diffs_metadata.json';
+ const noFilesData = { ...diffMetadata };
+ let mock;
+
+ beforeEach(() => {
+ mock = new MockAdapter(axios);
+
+ delete noFilesData.diff_files;
+ mock.onGet(endpointMetadata).reply(200, diffMetadata);
+ });
+ it('should fetch diff meta information', done => {
testAction(
fetchDiffFilesMeta,
{},
@@ -328,8 +416,8 @@ describe('DiffsStoreActions', () => {
[
{ 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 } },
+ { type: types.SET_MERGE_REQUEST_DIFFS, payload: diffMetadata.merge_request_diffs },
+ { type: types.SET_DIFF_DATA, payload: noFilesData },
],
[],
() => {
@@ -467,9 +555,9 @@ describe('DiffsStoreActions', () => {
new_path: 'file1',
old_line: 5,
old_path: 'file2',
+ line_range: null,
line_code: 'ABC_1_1',
position_type: 'text',
- line_range: null,
},
},
hash: 'ABC_123',
@@ -1136,34 +1224,8 @@ describe('DiffsStoreActions', () => {
});
});
- 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,
- { filePath: 'test' },
- {},
- [{ type: types.RECEIVE_FULL_DIFF_SUCCESS, payload: { filePath: 'test' } }],
- [],
- done,
- );
- });
- });
-
describe('receiveFullDiffError', () => {
- it('commits REQUEST_FULL_DIFF', done => {
+ it('updates state with the file that did not load', done => {
testAction(
receiveFullDiffError,
'file',
@@ -1191,7 +1253,7 @@ describe('DiffsStoreActions', () => {
mock.onGet(`${gl.TEST_HOST}/context`).replyOnce(200, ['test']);
});
- it('dispatches receiveFullDiffSucess', done => {
+ it('commits the success and dispatches an action to expand the new lines', done => {
const file = {
context_lines_path: `${gl.TEST_HOST}/context`,
file_path: 'test',
@@ -1201,11 +1263,8 @@ describe('DiffsStoreActions', () => {
fetchFullDiff,
file,
null,
- [],
- [
- { type: 'receiveFullDiffSucess', payload: { filePath: 'test' } },
- { type: 'setExpandedDiffLines', payload: { file, data: ['test'] } },
- ],
+ [{ type: types.RECEIVE_FULL_DIFF_SUCCESS, payload: { filePath: 'test' } }],
+ [{ type: 'setExpandedDiffLines', payload: { file, data: ['test'] } }],
done,
);
});
@@ -1243,11 +1302,8 @@ describe('DiffsStoreActions', () => {
toggleFullDiff,
'test',
state,
- [],
- [
- { type: 'requestFullDiff', payload: 'test' },
- { type: 'fetchFullDiff', payload: state.diffFiles[0] },
- ],
+ [{ type: types.REQUEST_FULL_DIFF, payload: 'test' }],
+ [{ type: 'fetchFullDiff', payload: state.diffFiles[0] }],
done,
);
});
@@ -1255,7 +1311,6 @@ describe('DiffsStoreActions', () => {
describe('switchToFullDiffFromRenamedFile', () => {
const SUCCESS_URL = 'fakehost/context.success';
- const ERROR_URL = 'fakehost/context.error';
const testFilePath = 'testpath';
const updatedViewerName = 'testviewer';
const preparedLine = { prepared: 'in-a-test' };
@@ -1311,27 +1366,6 @@ describe('DiffsStoreActions', () => {
},
);
});
-
- describe('error', () => {
- beforeEach(() => {
- renamedFile = { ...testFile, context_lines_path: ERROR_URL };
- mock.onGet(ERROR_URL).reply(500);
- });
-
- it('dispatches the error handling action', () => {
- const rejected = testAction(
- switchToFullDiffFromRenamedFile,
- { diffFile: renamedFile },
- null,
- [],
- [{ type: 'receiveFullDiffError', payload: testFilePath }],
- );
-
- return rejected.catch(error =>
- expect(error).toEqual(new Error('Request failed with status code 500')),
- );
- });
- });
});
describe('setFileCollapsed', () => {
diff --git a/spec/frontend/diffs/store/utils_spec.js b/spec/frontend/diffs/store/utils_spec.js
index 641373e666f..891de45e268 100644
--- a/spec/frontend/diffs/store/utils_spec.js
+++ b/spec/frontend/diffs/store/utils_spec.js
@@ -14,9 +14,11 @@ import {
} from '~/diffs/constants';
import { MERGE_REQUEST_NOTEABLE_TYPE } from '~/notes/constants';
import diffFileMockData from '../mock_data/diff_file';
+import { diffMetadata } from '../mock_data/diff_metadata';
import { noteableDataMock } from '../../notes/mock_data';
const getDiffFileMock = () => JSON.parse(JSON.stringify(diffFileMockData));
+const getDiffMetadataMock = () => JSON.parse(JSON.stringify(diffMetadata));
describe('DiffsStoreUtils', () => {
describe('findDiffFile', () => {
@@ -187,6 +189,7 @@ describe('DiffsStoreUtils', () => {
},
diffViewType: PARALLEL_DIFF_VIEW_TYPE,
linePosition: LINE_POSITION_LEFT,
+ lineRange: { start_line_code: 'abc_1_1', end_line_code: 'abc_2_2' },
};
const position = JSON.stringify({
@@ -198,6 +201,7 @@ describe('DiffsStoreUtils', () => {
position_type: TEXT_DIFF_POSITION_TYPE,
old_line: options.noteTargetLine.old_line,
new_line: options.noteTargetLine.new_line,
+ line_range: options.lineRange,
});
const postData = {
@@ -428,112 +432,177 @@ describe('DiffsStoreUtils', () => {
});
describe('prepareDiffData', () => {
- let mock;
- let preparedDiff;
- let splitInlineDiff;
- let splitParallelDiff;
- let completedDiff;
+ describe('for regular diff files', () => {
+ let mock;
+ let preparedDiff;
+ let splitInlineDiff;
+ let splitParallelDiff;
+ let completedDiff;
+
+ beforeEach(() => {
+ mock = getDiffFileMock();
+
+ preparedDiff = { diff_files: [mock] };
+ splitInlineDiff = {
+ diff_files: [{ ...mock, parallel_diff_lines: undefined }],
+ };
+ splitParallelDiff = {
+ diff_files: [{ ...mock, highlighted_diff_lines: undefined }],
+ };
+ completedDiff = {
+ diff_files: [{ ...mock, highlighted_diff_lines: undefined }],
+ };
- beforeEach(() => {
- mock = getDiffFileMock();
- preparedDiff = { diff_files: [mock] };
- splitInlineDiff = {
- diff_files: [{ ...mock, parallel_diff_lines: undefined }],
- };
- splitParallelDiff = {
- diff_files: [{ ...mock, highlighted_diff_lines: undefined }],
- };
- completedDiff = {
- diff_files: [{ ...mock, highlighted_diff_lines: undefined }],
- };
+ preparedDiff.diff_files = utils.prepareDiffData(preparedDiff);
+ splitInlineDiff.diff_files = utils.prepareDiffData(splitInlineDiff);
+ splitParallelDiff.diff_files = utils.prepareDiffData(splitParallelDiff);
+ completedDiff.diff_files = utils.prepareDiffData(completedDiff, [mock]);
+ });
- preparedDiff.diff_files = utils.prepareDiffData(preparedDiff);
- splitInlineDiff.diff_files = utils.prepareDiffData(splitInlineDiff);
- splitParallelDiff.diff_files = utils.prepareDiffData(splitParallelDiff);
- completedDiff.diff_files = utils.prepareDiffData(completedDiff, [mock]);
- });
+ it('sets the renderIt and collapsed attribute on files', () => {
+ const firstParallelDiffLine = preparedDiff.diff_files[0].parallel_diff_lines[2];
- it('sets the renderIt and collapsed attribute on files', () => {
- const firstParallelDiffLine = preparedDiff.diff_files[0].parallel_diff_lines[2];
+ expect(firstParallelDiffLine.left.discussions.length).toBe(0);
+ expect(firstParallelDiffLine.left).not.toHaveAttr('text');
+ expect(firstParallelDiffLine.right.discussions.length).toBe(0);
+ expect(firstParallelDiffLine.right).not.toHaveAttr('text');
+ const firstParallelChar = firstParallelDiffLine.right.rich_text.charAt(0);
- expect(firstParallelDiffLine.left.discussions.length).toBe(0);
- expect(firstParallelDiffLine.left).not.toHaveAttr('text');
- expect(firstParallelDiffLine.right.discussions.length).toBe(0);
- expect(firstParallelDiffLine.right).not.toHaveAttr('text');
- const firstParallelChar = firstParallelDiffLine.right.rich_text.charAt(0);
+ expect(firstParallelChar).not.toBe(' ');
+ expect(firstParallelChar).not.toBe('+');
+ expect(firstParallelChar).not.toBe('-');
- expect(firstParallelChar).not.toBe(' ');
- expect(firstParallelChar).not.toBe('+');
- expect(firstParallelChar).not.toBe('-');
+ const checkLine = preparedDiff.diff_files[0].highlighted_diff_lines[0];
- const checkLine = preparedDiff.diff_files[0].highlighted_diff_lines[0];
+ expect(checkLine.discussions.length).toBe(0);
+ expect(checkLine).not.toHaveAttr('text');
+ const firstChar = checkLine.rich_text.charAt(0);
- expect(checkLine.discussions.length).toBe(0);
- expect(checkLine).not.toHaveAttr('text');
- const firstChar = checkLine.rich_text.charAt(0);
+ expect(firstChar).not.toBe(' ');
+ expect(firstChar).not.toBe('+');
+ expect(firstChar).not.toBe('-');
- expect(firstChar).not.toBe(' ');
- expect(firstChar).not.toBe('+');
- expect(firstChar).not.toBe('-');
+ expect(preparedDiff.diff_files[0].renderIt).toBeTruthy();
+ expect(preparedDiff.diff_files[0].collapsed).toBeFalsy();
+ });
- expect(preparedDiff.diff_files[0].renderIt).toBeTruthy();
- expect(preparedDiff.diff_files[0].collapsed).toBeFalsy();
- });
+ it('adds line_code to all lines', () => {
+ expect(
+ preparedDiff.diff_files[0].parallel_diff_lines.filter(line => !line.line_code),
+ ).toHaveLength(0);
+ });
- it('adds line_code to all lines', () => {
- expect(
- preparedDiff.diff_files[0].parallel_diff_lines.filter(line => !line.line_code),
- ).toHaveLength(0);
- });
+ it('uses right line code if left has none', () => {
+ const firstLine = preparedDiff.diff_files[0].parallel_diff_lines[0];
- it('uses right line code if left has none', () => {
- const firstLine = preparedDiff.diff_files[0].parallel_diff_lines[0];
+ expect(firstLine.line_code).toEqual(firstLine.right.line_code);
+ });
- expect(firstLine.line_code).toEqual(firstLine.right.line_code);
- });
+ it('guarantees an empty array for both diff styles', () => {
+ expect(splitInlineDiff.diff_files[0].parallel_diff_lines.length).toEqual(0);
+ expect(splitInlineDiff.diff_files[0].highlighted_diff_lines.length).toBeGreaterThan(0);
+ expect(splitParallelDiff.diff_files[0].parallel_diff_lines.length).toBeGreaterThan(0);
+ expect(splitParallelDiff.diff_files[0].highlighted_diff_lines.length).toEqual(0);
+ });
- it('guarantees an empty array for both diff styles', () => {
- expect(splitInlineDiff.diff_files[0].parallel_diff_lines.length).toEqual(0);
- expect(splitInlineDiff.diff_files[0].highlighted_diff_lines.length).toBeGreaterThan(0);
- expect(splitParallelDiff.diff_files[0].parallel_diff_lines.length).toBeGreaterThan(0);
- expect(splitParallelDiff.diff_files[0].highlighted_diff_lines.length).toEqual(0);
- });
+ it('merges existing diff files with newly loaded diff files to ensure split diffs are eventually completed', () => {
+ expect(completedDiff.diff_files.length).toEqual(1);
+ expect(completedDiff.diff_files[0].parallel_diff_lines.length).toBeGreaterThan(0);
+ expect(completedDiff.diff_files[0].highlighted_diff_lines.length).toBeGreaterThan(0);
+ });
- it('merges existing diff files with newly loaded diff files to ensure split diffs are eventually completed', () => {
- expect(completedDiff.diff_files.length).toEqual(1);
- expect(completedDiff.diff_files[0].parallel_diff_lines.length).toBeGreaterThan(0);
- expect(completedDiff.diff_files[0].highlighted_diff_lines.length).toBeGreaterThan(0);
- });
+ it('leaves files in the existing state', () => {
+ const priorFiles = [mock];
+ const fakeNewFile = {
+ ...mock,
+ content_sha: 'ABC',
+ file_hash: 'DEF',
+ };
+ const updatedFilesList = utils.prepareDiffData({ diff_files: [fakeNewFile] }, priorFiles);
- it('leaves files in the existing state', () => {
- const priorFiles = [mock];
- const fakeNewFile = {
- ...mock,
- content_sha: 'ABC',
- file_hash: 'DEF',
- };
- const updatedFilesList = utils.prepareDiffData({ diff_files: [fakeNewFile] }, priorFiles);
+ expect(updatedFilesList).toEqual([mock, fakeNewFile]);
+ });
- expect(updatedFilesList).toEqual([mock, fakeNewFile]);
+ it('completes an existing split diff without overwriting existing diffs', () => {
+ // The current state has a file that has only loaded inline lines
+ const priorFiles = [{ ...mock, parallel_diff_lines: [] }];
+ // The next (batch) load loads two files: the other half of that file, and a new file
+ const fakeBatch = [
+ { ...mock, highlighted_diff_lines: undefined },
+ { ...mock, highlighted_diff_lines: undefined, content_sha: 'ABC', file_hash: 'DEF' },
+ ];
+ const updatedFilesList = utils.prepareDiffData({ diff_files: fakeBatch }, priorFiles);
+
+ expect(updatedFilesList).toEqual([
+ mock,
+ expect.objectContaining({
+ content_sha: 'ABC',
+ file_hash: 'DEF',
+ }),
+ ]);
+ });
});
- it('completes an existing split diff without overwriting existing diffs', () => {
- // The current state has a file that has only loaded inline lines
- const priorFiles = [{ ...mock, parallel_diff_lines: [] }];
- // The next (batch) load loads two files: the other half of that file, and a new file
- const fakeBatch = [
- { ...mock, highlighted_diff_lines: undefined },
- { ...mock, highlighted_diff_lines: undefined, content_sha: 'ABC', file_hash: 'DEF' },
- ];
- const updatedFilesList = utils.prepareDiffData({ diff_files: fakeBatch }, priorFiles);
+ describe('for diff metadata', () => {
+ let mock;
+ let preparedDiffFiles;
- expect(updatedFilesList).toEqual([
- mock,
- expect.objectContaining({
- content_sha: 'ABC',
- file_hash: 'DEF',
- }),
- ]);
+ beforeEach(() => {
+ mock = getDiffMetadataMock();
+
+ preparedDiffFiles = utils.prepareDiffData(mock);
+ });
+
+ it('sets the renderIt and collapsed attribute on files', () => {
+ expect(preparedDiffFiles[0].renderIt).toBeTruthy();
+ expect(preparedDiffFiles[0].collapsed).toBeFalsy();
+ });
+
+ it('guarantees an empty array of lines for both diff styles', () => {
+ expect(preparedDiffFiles[0].parallel_diff_lines.length).toEqual(0);
+ expect(preparedDiffFiles[0].highlighted_diff_lines.length).toEqual(0);
+ });
+
+ it('leaves files in the existing state', () => {
+ const fileMock = getDiffFileMock();
+ const metaData = getDiffMetadataMock();
+ const priorFiles = [fileMock];
+ const updatedFilesList = utils.prepareDiffData(metaData, priorFiles);
+
+ expect(updatedFilesList.length).toEqual(2);
+ expect(updatedFilesList[0]).toEqual(fileMock);
+ });
+
+ it('adds a new file to the file that already exists in state', () => {
+ // This is actually buggy behavior:
+ // Because the metadata doesn't include a content_sha,
+ // the de-duplicator in prepareDiffData doesn't realize it
+ // should combine these two.
+
+ // This buggy behavior hasn't caused a defect YET, because
+ // `diffs_metadata.json` is only called the first time the
+ // diffs app starts up, which is:
+ // - after a fresh page load
+ // - after you switch to the changes tab *the first time*
+
+ // This test should begin FAILING and can be reversed to check
+ // for just a single file when this is implemented:
+ // https://gitlab.com/groups/gitlab-org/-/epics/2852#note_304803233
+
+ const fileMock = getDiffFileMock();
+ const metaMock = getDiffMetadataMock();
+ const priorFiles = [{ ...fileMock }];
+ const updatedFilesList = utils.prepareDiffData(metaMock, priorFiles);
+
+ expect(updatedFilesList).toEqual([
+ fileMock,
+ {
+ ...metaMock.diff_files[0],
+ highlighted_diff_lines: [],
+ parallel_diff_lines: [],
+ },
+ ]);
+ });
});
});
diff --git a/spec/frontend/diffs/utils/uuids_spec.js b/spec/frontend/diffs/utils/uuids_spec.js
new file mode 100644
index 00000000000..79d3ebadd4f
--- /dev/null
+++ b/spec/frontend/diffs/utils/uuids_spec.js
@@ -0,0 +1,92 @@
+import { uuids } from '~/diffs/utils/uuids';
+
+const HEX = /[a-f0-9]/i;
+const HEX_RE = HEX.source;
+const UUIDV4 = new RegExp(
+ `${HEX_RE}{8}-${HEX_RE}{4}-4${HEX_RE}{3}-[89ab]${HEX_RE}{3}-${HEX_RE}{12}`,
+ 'i',
+);
+
+describe('UUIDs Util', () => {
+ describe('uuids', () => {
+ const SEQUENCE_FOR_GITLAB_SEED = [
+ 'a1826a44-316c-480e-a93d-8cdfeb36617c',
+ 'e049db1f-a4cf-4cba-aa60-6d95e3b547dc',
+ '6e3c737c-13a7-4380-b17d-601f187d7e69',
+ 'bee5cc7f-c486-45c0-8ad3-d1ac5402632d',
+ 'af248c9f-a3a6-4d4f-a311-fe151ffab25a',
+ ];
+ const SEQUENCE_FOR_12345_SEED = [
+ 'edfb51e2-e3e1-4de5-90fd-fd1d21760881',
+ '2f154da4-0a2d-4da9-b45e-0ffed391517e',
+ '91566d65-8836-4222-9875-9e1df4d0bb01',
+ 'f6ea6c76-7640-4d71-a736-9d3bec7a1a8e',
+ 'bfb85869-5fb9-4c5b-a750-5af727ac5576',
+ ];
+
+ it('returns version 4 UUIDs', () => {
+ expect(uuids()[0]).toMatch(UUIDV4);
+ });
+
+ it('outputs an array of UUIDs', () => {
+ const ids = uuids({ count: 11 });
+
+ expect(ids.length).toEqual(11);
+ expect(ids.every(id => UUIDV4.test(id))).toEqual(true);
+ });
+
+ it.each`
+ seeds | uuid
+ ${['some', 'special', 'seed']} | ${'6fa53e51-0f70-4072-9c84-1c1eee1b9934'}
+ ${['magic']} | ${'fafae8cd-7083-44f3-b82d-43b30bd27486'}
+ ${['seeded']} | ${'e06ed291-46c5-4e42-836b-e7c772d48b49'}
+ ${['GitLab']} | ${'a1826a44-316c-480e-a93d-8cdfeb36617c'}
+ ${['JavaScript']} | ${'12dfb297-1560-4c38-9775-7178ef8472fb'}
+ ${[99, 169834, 2619]} | ${'3ecc8ad6-5b7c-4c9b-94a8-c7271c2fa083'}
+ ${[12]} | ${'2777374b-723b-469b-bd73-e586df964cfd'}
+ ${[9876, 'mixed!', 7654]} | ${'865212e0-4a16-4934-96f9-103cf36a6931'}
+ ${[123, 1234, 12345, 6]} | ${'40aa2ee6-0a11-4e67-8f09-72f5eba04244'}
+ ${[0]} | ${'8c7f0aac-97c4-4a2f-b716-a675d821ccc0'}
+ `(
+ 'should always output the UUID $uuid when the options.seeds argument is $seeds',
+ ({ uuid, seeds }) => {
+ expect(uuids({ seeds })[0]).toEqual(uuid);
+ },
+ );
+
+ describe('unseeded UUID randomness', () => {
+ const nonRandom = Array(6)
+ .fill(0)
+ .map((_, i) => uuids({ seeds: [i] })[0]);
+ const random = uuids({ count: 6 });
+ const moreRandom = uuids({ count: 6 });
+
+ it('is different from a seeded result', () => {
+ random.forEach((id, i) => {
+ expect(id).not.toEqual(nonRandom[i]);
+ });
+ });
+
+ it('is different from other random results', () => {
+ random.forEach((id, i) => {
+ expect(id).not.toEqual(moreRandom[i]);
+ });
+ });
+
+ it('never produces any duplicates', () => {
+ expect(new Set(random).size).toEqual(random.length);
+ });
+ });
+
+ it.each`
+ seed | sequence
+ ${'GitLab'} | ${SEQUENCE_FOR_GITLAB_SEED}
+ ${12345} | ${SEQUENCE_FOR_12345_SEED}
+ `(
+ 'should output the same sequence of UUIDs for the given seed "$seed"',
+ ({ seed, sequence }) => {
+ expect(uuids({ seeds: [seed], count: 5 })).toEqual(sequence);
+ },
+ );
+ });
+});