2021-09-04 01:27:46 +05:30
|
|
|
import {
|
|
|
|
prepareRawDiffFile,
|
|
|
|
getShortShaFromFile,
|
|
|
|
stats,
|
|
|
|
isNotDiffable,
|
2022-07-16 23:28:13 +05:30
|
|
|
match,
|
2021-09-04 01:27:46 +05:30
|
|
|
} from '~/diffs/utils/diff_file';
|
|
|
|
import { diffViewerModes } from '~/ide/constants';
|
2022-08-13 15:12:31 +05:30
|
|
|
import { getDiffFileMock } from '../mock_data/diff_file';
|
2021-02-22 17:27:13 +05:30
|
|
|
|
|
|
|
function getDiffFiles() {
|
2021-03-08 18:12:59 +05:30
|
|
|
const loadFull = 'namespace/project/-/merge_requests/12345/diff_for_path?file_identifier=abc';
|
|
|
|
|
2021-02-22 17:27:13 +05:30
|
|
|
return [
|
|
|
|
{
|
|
|
|
blob: {
|
|
|
|
id: 'C0473471',
|
|
|
|
},
|
|
|
|
file_hash: 'ABC', // This file is just a normal file
|
|
|
|
file_identifier_hash: 'ABC1',
|
2021-03-08 18:12:59 +05:30
|
|
|
load_collapsed_diff_url: loadFull,
|
2021-02-22 17:27:13 +05:30
|
|
|
},
|
|
|
|
{
|
|
|
|
blob: {
|
|
|
|
id: 'C0473472',
|
|
|
|
},
|
|
|
|
file_hash: 'DEF', // This file replaces a symlink
|
|
|
|
file_identifier_hash: 'DEF1',
|
2021-03-08 18:12:59 +05:30
|
|
|
load_collapsed_diff_url: loadFull,
|
2021-02-22 17:27:13 +05:30
|
|
|
a_mode: '0',
|
|
|
|
b_mode: '0755',
|
|
|
|
},
|
|
|
|
{
|
|
|
|
blob: {
|
|
|
|
id: 'C0473473',
|
|
|
|
},
|
|
|
|
file_hash: 'DEF', // This symlink is replaced by a file
|
|
|
|
file_identifier_hash: 'DEF2',
|
2021-03-08 18:12:59 +05:30
|
|
|
load_collapsed_diff_url: loadFull,
|
2021-02-22 17:27:13 +05:30
|
|
|
a_mode: '120000',
|
|
|
|
b_mode: '0',
|
|
|
|
},
|
|
|
|
{
|
|
|
|
blob: {
|
|
|
|
id: 'C0473474',
|
|
|
|
},
|
|
|
|
file_hash: 'GHI', // This symlink replaces a file
|
|
|
|
file_identifier_hash: 'GHI1',
|
2021-03-08 18:12:59 +05:30
|
|
|
load_collapsed_diff_url: loadFull,
|
2021-02-22 17:27:13 +05:30
|
|
|
a_mode: '0',
|
|
|
|
b_mode: '120000',
|
|
|
|
},
|
|
|
|
{
|
|
|
|
blob: {
|
|
|
|
id: 'C0473475',
|
|
|
|
},
|
|
|
|
file_hash: 'GHI', // This file is replaced by a symlink
|
|
|
|
file_identifier_hash: 'GHI2',
|
2021-03-08 18:12:59 +05:30
|
|
|
load_collapsed_diff_url: loadFull,
|
2021-02-22 17:27:13 +05:30
|
|
|
a_mode: '0755',
|
|
|
|
b_mode: '0',
|
|
|
|
},
|
|
|
|
];
|
|
|
|
}
|
|
|
|
function makeBrokenSymlinkObject(replaced, wasSymbolic, isSymbolic, wasReal, isReal) {
|
|
|
|
return {
|
|
|
|
replaced,
|
|
|
|
wasSymbolic,
|
|
|
|
isSymbolic,
|
|
|
|
wasReal,
|
|
|
|
isReal,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
describe('diff_file utilities', () => {
|
|
|
|
describe('prepareRawDiffFile', () => {
|
|
|
|
let files;
|
|
|
|
|
|
|
|
beforeEach(() => {
|
|
|
|
files = getDiffFiles();
|
|
|
|
});
|
|
|
|
|
|
|
|
it.each`
|
|
|
|
fileIndex | description | brokenSymlink
|
|
|
|
${0} | ${'a file that is not symlink-adjacent'} | ${false}
|
|
|
|
${1} | ${'a file that replaces a symlink'} | ${makeBrokenSymlinkObject(false, false, false, false, true)}
|
|
|
|
${2} | ${'a symlink that is replaced by a file'} | ${makeBrokenSymlinkObject(true, true, false, false, false)}
|
|
|
|
${3} | ${'a symlink that replaces a file'} | ${makeBrokenSymlinkObject(false, false, true, false, false)}
|
|
|
|
${4} | ${'a file that is replaced by a symlink'} | ${makeBrokenSymlinkObject(true, false, false, true, false)}
|
|
|
|
`(
|
|
|
|
'properly marks $description with the correct .brokenSymlink value',
|
|
|
|
({ fileIndex, brokenSymlink }) => {
|
|
|
|
const preppedRaw = prepareRawDiffFile({
|
|
|
|
file: files[fileIndex],
|
|
|
|
allFiles: files,
|
|
|
|
});
|
|
|
|
|
|
|
|
expect(preppedRaw.brokenSymlink).toStrictEqual(brokenSymlink);
|
|
|
|
},
|
|
|
|
);
|
|
|
|
|
|
|
|
it.each`
|
|
|
|
fileIndex | id
|
2021-03-08 18:12:59 +05:30
|
|
|
${0} | ${'68296a4f-f1c7-445a-bd0e-6e3b02c4eec0'}
|
|
|
|
${1} | ${'051c9bb8-cdba-4eb7-b8d1-508906e6d8ba'}
|
|
|
|
${2} | ${'ed3d53d5-5da0-412d-a3c6-7213f84e88d3'}
|
|
|
|
${3} | ${'39d998dc-bc69-4b19-a6af-41e4369c2bd5'}
|
|
|
|
${4} | ${'7072d115-ce39-423c-8346-9fcad58cd68e'}
|
2021-02-22 17:27:13 +05:30
|
|
|
`('sets the file id properly { id: $id } on normal diff files', ({ fileIndex, id }) => {
|
|
|
|
const preppedFile = prepareRawDiffFile({
|
|
|
|
file: files[fileIndex],
|
|
|
|
allFiles: files,
|
|
|
|
});
|
|
|
|
|
|
|
|
expect(preppedFile.id).toBe(id);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('does not set the `id` property for metadata diff files', () => {
|
|
|
|
const preppedFile = prepareRawDiffFile({
|
|
|
|
file: files[0],
|
|
|
|
allFiles: files,
|
|
|
|
meta: true,
|
|
|
|
});
|
|
|
|
|
|
|
|
expect(preppedFile).not.toHaveProp('id');
|
|
|
|
});
|
|
|
|
|
|
|
|
it('does not set the id property if the file is missing a `blob.id`', () => {
|
|
|
|
const fileMissingContentSha = { ...files[0] };
|
|
|
|
|
|
|
|
delete fileMissingContentSha.blob.id;
|
|
|
|
|
|
|
|
const preppedFile = prepareRawDiffFile({
|
|
|
|
file: fileMissingContentSha,
|
|
|
|
allFiles: files,
|
|
|
|
});
|
|
|
|
|
|
|
|
expect(preppedFile).not.toHaveProp('id');
|
|
|
|
});
|
2021-03-08 18:12:59 +05:30
|
|
|
|
|
|
|
it('does not set the id property if the file is missing a `load_collapsed_diff_url` property', () => {
|
|
|
|
const fileMissingContentSha = { ...files[0] };
|
|
|
|
|
|
|
|
delete fileMissingContentSha.load_collapsed_diff_url;
|
|
|
|
|
|
|
|
const preppedFile = prepareRawDiffFile({
|
|
|
|
file: fileMissingContentSha,
|
|
|
|
allFiles: files,
|
|
|
|
});
|
|
|
|
|
|
|
|
expect(preppedFile).not.toHaveProp('id');
|
|
|
|
});
|
2022-07-16 23:28:13 +05:30
|
|
|
|
|
|
|
it.each`
|
|
|
|
index
|
|
|
|
${null}
|
|
|
|
${undefined}
|
|
|
|
${-1}
|
|
|
|
${false}
|
|
|
|
${true}
|
|
|
|
${'idx'}
|
|
|
|
${'42'}
|
|
|
|
`('does not set the order property if an invalid index ($index) is provided', ({ index }) => {
|
|
|
|
const preppedFile = prepareRawDiffFile({
|
|
|
|
file: files[0],
|
|
|
|
allFiles: files,
|
|
|
|
index,
|
|
|
|
});
|
|
|
|
|
|
|
|
/* expect.anything() doesn't match null or undefined */
|
|
|
|
expect(preppedFile).toEqual(expect.not.objectContaining({ order: null }));
|
|
|
|
expect(preppedFile).toEqual(expect.not.objectContaining({ order: undefined }));
|
|
|
|
expect(preppedFile).toEqual(expect.not.objectContaining({ order: expect.anything() }));
|
|
|
|
});
|
|
|
|
|
|
|
|
it('sets the provided valid index to the order property', () => {
|
|
|
|
const preppedFile = prepareRawDiffFile({
|
|
|
|
file: files[0],
|
|
|
|
allFiles: files,
|
|
|
|
index: 42,
|
|
|
|
});
|
|
|
|
|
|
|
|
expect(preppedFile).toEqual(expect.objectContaining({ order: 42 }));
|
|
|
|
});
|
2021-02-22 17:27:13 +05:30
|
|
|
});
|
2021-03-11 19:13:27 +05:30
|
|
|
|
|
|
|
describe('getShortShaFromFile', () => {
|
|
|
|
it.each`
|
|
|
|
response | cs
|
|
|
|
${'12345678'} | ${'12345678abcdogcat'}
|
|
|
|
${null} | ${undefined}
|
|
|
|
${'hidogcat'} | ${'hidogcatmorethings'}
|
|
|
|
`('returns $response for a file with { content_sha: $cs }', ({ response, cs }) => {
|
|
|
|
expect(getShortShaFromFile({ content_sha: cs })).toBe(response);
|
|
|
|
});
|
|
|
|
});
|
2021-09-04 01:27:46 +05:30
|
|
|
|
|
|
|
describe('stats', () => {
|
|
|
|
const noFile = [
|
|
|
|
"returns empty stats when the file isn't provided",
|
|
|
|
undefined,
|
|
|
|
{
|
|
|
|
text: '',
|
|
|
|
percent: 0,
|
|
|
|
changed: 0,
|
|
|
|
classes: '',
|
|
|
|
sign: '',
|
|
|
|
valid: false,
|
|
|
|
},
|
|
|
|
];
|
|
|
|
const validFile = [
|
|
|
|
'computes the correct stats from a file',
|
2022-08-13 15:12:31 +05:30
|
|
|
getDiffFileMock(),
|
2021-09-04 01:27:46 +05:30
|
|
|
{
|
|
|
|
changed: 1024,
|
|
|
|
percent: 100,
|
|
|
|
classes: 'gl-text-green-600',
|
|
|
|
sign: '+',
|
|
|
|
text: '+1.00 KiB (+100%)',
|
|
|
|
valid: true,
|
|
|
|
},
|
|
|
|
];
|
|
|
|
const negativeChange = [
|
|
|
|
'computed the correct states from a file with a negative size change',
|
|
|
|
{
|
2022-08-13 15:12:31 +05:30
|
|
|
...getDiffFileMock(),
|
2021-09-04 01:27:46 +05:30
|
|
|
new_size: 0,
|
|
|
|
old_size: 1024,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
changed: -1024,
|
|
|
|
percent: -100,
|
|
|
|
classes: 'gl-text-red-500',
|
|
|
|
sign: '',
|
|
|
|
text: '-1.00 KiB (-100%)',
|
|
|
|
valid: true,
|
|
|
|
},
|
|
|
|
];
|
|
|
|
|
|
|
|
it.each([noFile, validFile, negativeChange])('%s', (_, file, output) => {
|
|
|
|
expect(stats(file)).toEqual(output);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('isNotDiffable', () => {
|
|
|
|
it.each`
|
|
|
|
bool | vw
|
|
|
|
${true} | ${diffViewerModes.not_diffable}
|
|
|
|
${false} | ${diffViewerModes.text}
|
|
|
|
${false} | ${diffViewerModes.image}
|
|
|
|
`('returns $bool when the viewer is $vw', ({ bool, vw }) => {
|
|
|
|
expect(isNotDiffable({ viewer: { name: vw } })).toBe(bool);
|
|
|
|
});
|
|
|
|
|
|
|
|
it.each`
|
|
|
|
file
|
|
|
|
${undefined}
|
|
|
|
${null}
|
|
|
|
${{}}
|
|
|
|
${{ viewer: undefined }}
|
|
|
|
${{ viewer: null }}
|
|
|
|
`('reports `false` when the file is `$file`', ({ file }) => {
|
|
|
|
expect(isNotDiffable(file)).toBe(false);
|
|
|
|
});
|
|
|
|
});
|
2022-07-16 23:28:13 +05:30
|
|
|
|
|
|
|
describe('match', () => {
|
|
|
|
const authorityFileId = '68296a4f-f1c7-445a-bd0e-6e3b02c4eec0';
|
|
|
|
const fih = 'file_identifier_hash';
|
|
|
|
const fihs = 'file identifier hashes';
|
|
|
|
let authorityFile;
|
|
|
|
|
|
|
|
beforeAll(() => {
|
|
|
|
const files = getDiffFiles();
|
|
|
|
|
|
|
|
authorityFile = prepareRawDiffFile({
|
|
|
|
file: files[0],
|
|
|
|
allFiles: files,
|
|
|
|
});
|
|
|
|
|
|
|
|
Object.freeze(authorityFile);
|
|
|
|
});
|
|
|
|
|
|
|
|
describe.each`
|
|
|
|
mode | comparisonFiles | keyName
|
|
|
|
${'universal'} | ${[{ [fih]: 'ABC1' }, { id: 'foo' }, { id: authorityFileId }]} | ${'ids'}
|
|
|
|
${'mr'} | ${[{ id: authorityFileId }, { [fih]: 'ABC2' }, { [fih]: 'ABC1' }]} | ${fihs}
|
|
|
|
`('$mode mode', ({ mode, comparisonFiles, keyName }) => {
|
|
|
|
it(`fails to match if files or ${keyName} aren't present`, () => {
|
|
|
|
expect(match({ fileA: authorityFile, fileB: undefined, mode })).toBe(false);
|
|
|
|
expect(match({ fileA: authorityFile, fileB: null, mode })).toBe(false);
|
|
|
|
expect(match({ fileA: authorityFile, fileB: comparisonFiles[0], mode })).toBe(false);
|
|
|
|
});
|
|
|
|
|
|
|
|
it(`fails to match if the ${keyName} aren't the same`, () => {
|
|
|
|
expect(match({ fileA: authorityFile, fileB: comparisonFiles[1], mode })).toBe(false);
|
|
|
|
});
|
|
|
|
|
|
|
|
it(`matches if the ${keyName} are the same`, () => {
|
|
|
|
expect(match({ fileA: authorityFile, fileB: comparisonFiles[2], mode })).toBe(true);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
2021-02-22 17:27:13 +05:30
|
|
|
});
|