diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-06-18 14:18:50 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-06-18 14:18:50 +0300 |
commit | 8c7f4e9d5f36cff46365a7f8c4b9c21578c1e781 (patch) | |
tree | a77e7fe7a93de11213032ed4ab1f33a3db51b738 /spec/frontend/diffs/store | |
parent | 00b35af3db1abfe813a778f643dad221aad51fca (diff) |
Add latest changes from gitlab-org/gitlab@13-1-stable-ee
Diffstat (limited to 'spec/frontend/diffs/store')
-rw-r--r-- | spec/frontend/diffs/store/actions_spec.js | 228 | ||||
-rw-r--r-- | spec/frontend/diffs/store/utils_spec.js | 243 |
2 files changed, 287 insertions, 184 deletions
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: [], + }, + ]); + }); }); }); |