diff --git a/app/assets/javascripts/diffs/store/utils.js b/app/assets/javascripts/diffs/store/utils.js index d261be1b5509199a7e2c3dfbba5689d0f9c8fabc..732b5850626d10a959b98ef1c775e6c95093ac43 100644 --- a/app/assets/javascripts/diffs/store/utils.js +++ b/app/assets/javascripts/diffs/store/utils.js @@ -16,6 +16,7 @@ import { INLINE_DIFF_VIEW_TYPE, PARALLEL_DIFF_VIEW_TYPE, } from '../constants'; +import { uuids } from '../utils/uuids'; export function findDiffFile(files, match, matchKey = 'file_hash') { return files.find(file => file[matchKey] === match); @@ -403,8 +404,26 @@ function deduplicateFilesList(files) { return Object.values(dedupedFiles); } +function prepareDiffFile(file) { + Object.assign(file, { + uuid: uuids({ + seeds: [ + file.blob.id, + file.diff_refs.base_sha, + file.diff_refs.start_sha, + file.diff_refs.head_sha, + file.file_identifier_hash, + Number(file.blob.mode), + ], + })[0], + }); + + return file; +} + export function prepareDiffData(diff, priorFiles = []) { const cleanedFiles = (diff.diff_files || []) + .map(prepareDiffFile) .map(ensureBasicDiffFileLines) .map(prepareDiffFileLines) .map(finalizeDiffFile); diff --git a/spec/frontend/diffs/mock_data/diff_file.js b/spec/frontend/diffs/mock_data/diff_file.js index 27428197c1c9d2261165e563b24c5d62e852664a..e4b2fdf6ededb954a4a6f98f22237ea80749556b 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: '', file_hash: '1c497fbb3a46b78edf04cc2a2fa33f67e3ffbe2a', + file_identifier_hash: '928f8286952bda02d674b692addcbe077084663a', file_path: 'CHANGELOG', new_file: false, deleted_file: false, diff --git a/spec/frontend/diffs/store/mutations_spec.js b/spec/frontend/diffs/store/mutations_spec.js index c24d406fef319a9a0cdd57ec30f6aa03b5bcb370..f48321467082eb2c627599deee0e162cc79f3ddc 100644 --- a/spec/frontend/diffs/store/mutations_spec.js +++ b/spec/frontend/diffs/store/mutations_spec.js @@ -243,6 +243,8 @@ describe('DiffsStoreMutations', () => { const data = { diff_files: [ { + blob: {}, + diff_refs: {}, content_sha: 'abc', file_hash: fileHash, extra_field: 1, diff --git a/spec/frontend/diffs/store/utils_spec.js b/spec/frontend/diffs/store/utils_spec.js index 296069afa2ca4872ed48e2d95773082cbd929b76..9879b4dd3f6fa4fb827ed22cd5562250af8666f9 100644 --- a/spec/frontend/diffs/store/utils_spec.js +++ b/spec/frontend/diffs/store/utils_spec.js @@ -1,5 +1,6 @@ import { clone } from 'lodash'; import * as utils from '~/diffs/store/utils'; +import { uuids } from '~/diffs/utils/uuids'; import { LINE_POSITION_LEFT, LINE_POSITION_RIGHT, @@ -430,6 +431,7 @@ describe('DiffsStoreUtils', () => { }); describe('prepareDiffData', () => { + let fileId; let mock; let preparedDiff; let splitInlineDiff; @@ -438,6 +440,17 @@ describe('DiffsStoreUtils', () => { beforeEach(() => { mock = getDiffFileMock(); + [fileId] = uuids({ + seeds: [ + mock.blob.id, + mock.diff_refs.base_sha, + mock.diff_refs.start_sha, + mock.diff_refs.head_sha, + mock.file_identifier_hash, + Number(mock.blob.mode), + ], + }); + preparedDiff = { diff_files: [mock] }; splitInlineDiff = { diff_files: [{ ...mock, parallel_diff_lines: undefined }], @@ -455,6 +468,13 @@ describe('DiffsStoreUtils', () => { completedDiff.diff_files = utils.prepareDiffData(completedDiff, [mock]); }); + it('adds a universally unique identifier to each diff file', () => { + expect(preparedDiff.diff_files[0].uuid).toBe(fileId); + expect(splitInlineDiff.diff_files[0].uuid).toBe(fileId); + expect(splitParallelDiff.diff_files[0].uuid).toBe(fileId); + expect(completedDiff.diff_files[0].uuid).toBe(fileId); + }); + it('sets the renderIt and collapsed attribute on files', () => { const firstParallelDiffLine = preparedDiff.diff_files[0].parallel_diff_lines[2];