2018-11-08 19:23:39 +05:30
import {
LINE _POSITION _LEFT ,
LINE _POSITION _RIGHT ,
TEXT _DIFF _POSITION _TYPE ,
2018-12-05 23:21:45 +05:30
LEGACY _DIFF _NOTE _TYPE ,
2018-11-08 19:23:39 +05:30
DIFF _NOTE _TYPE ,
NEW _LINE _TYPE ,
OLD _LINE _TYPE ,
MATCH _LINE _TYPE ,
2020-04-08 14:13:33 +05:30
INLINE _DIFF _VIEW _TYPE ,
2021-02-22 17:27:13 +05:30
INLINE _DIFF _LINES _KEY ,
2018-11-08 19:23:39 +05:30
} from '~/diffs/constants' ;
2021-03-11 19:13:27 +05:30
import * as utils from '~/diffs/store/utils' ;
2018-11-08 19:23:39 +05:30
import { MERGE _REQUEST _NOTEABLE _TYPE } from '~/notes/constants' ;
2022-06-21 17:19:12 +05:30
import { noteableDataMock } from 'jest/notes/mock_data' ;
2022-08-13 15:12:31 +05:30
import { getDiffFileMock } from '../mock_data/diff_file' ;
2020-06-23 00:09:42 +05:30
import { diffMetadata } from '../mock_data/diff_metadata' ;
2018-11-08 19:23:39 +05:30
2020-06-23 00:09:42 +05:30
const getDiffMetadataMock = ( ) => JSON . parse ( JSON . stringify ( diffMetadata ) ) ;
2018-11-08 19:23:39 +05:30
describe ( 'DiffsStoreUtils' , ( ) => {
describe ( 'findDiffFile' , ( ) => {
2019-02-15 15:39:39 +05:30
const files = [ { file _hash : 1 , name : 'one' } ] ;
2018-11-08 19:23:39 +05:30
it ( 'should return correct file' , ( ) => {
expect ( utils . findDiffFile ( files , 1 ) . name ) . toEqual ( 'one' ) ;
expect ( utils . findDiffFile ( files , 2 ) ) . toBeUndefined ( ) ;
} ) ;
} ) ;
2021-02-22 17:27:13 +05:30
describe ( 'findIndexInInlineLines' , ( ) => {
2018-11-08 19:23:39 +05:30
const expectSet = ( method , lines , invalidLines ) => {
expect ( method ( lines , { oldLineNumber : 3 , newLineNumber : 5 } ) ) . toEqual ( 4 ) ;
expect ( method ( invalidLines || lines , { oldLineNumber : 32 , newLineNumber : 53 } ) ) . toEqual ( - 1 ) ;
} ;
describe ( 'findIndexInInlineLines' , ( ) => {
it ( 'should return correct index for given line numbers' , ( ) => {
2021-02-22 17:27:13 +05:30
expectSet ( utils . findIndexInInlineLines , getDiffFileMock ( ) [ INLINE _DIFF _LINES _KEY ] ) ;
2020-04-08 14:13:33 +05:30
} ) ;
} ) ;
} ) ;
describe ( 'getPreviousLineIndex' , ( ) => {
2022-07-16 23:28:13 +05:30
let diffFile ;
2020-04-08 14:13:33 +05:30
2022-07-16 23:28:13 +05:30
beforeEach ( ( ) => {
2022-08-13 15:12:31 +05:30
diffFile = getDiffFileMock ( ) ;
2022-07-16 23:28:13 +05:30
} ) ;
2021-02-22 17:27:13 +05:30
2022-07-16 23:28:13 +05:30
it ( 'should return the correct previous line number' , ( ) => {
expect (
utils . getPreviousLineIndex ( diffFile , {
oldLineNumber : 3 ,
newLineNumber : 5 ,
} ) ,
) . toBe ( 4 ) ;
2018-11-08 19:23:39 +05:30
} ) ;
} ) ;
describe ( 'removeMatchLine' , ( ) => {
it ( 'should remove match line properly by regarding the bottom parameter' , ( ) => {
const diffFile = getDiffFileMock ( ) ;
const lineNumbers = { oldLineNumber : 3 , newLineNumber : 5 } ;
2019-02-15 15:39:39 +05:30
const inlineIndex = utils . findIndexInInlineLines (
2021-02-22 17:27:13 +05:30
diffFile [ INLINE _DIFF _LINES _KEY ] ,
2019-02-15 15:39:39 +05:30
lineNumbers ,
) ;
2021-02-22 17:27:13 +05:30
const atInlineIndex = diffFile [ INLINE _DIFF _LINES _KEY ] [ inlineIndex ] ;
2018-11-08 19:23:39 +05:30
utils . removeMatchLine ( diffFile , lineNumbers , false ) ;
2018-12-13 13:39:08 +05:30
2021-02-22 17:27:13 +05:30
expect ( diffFile [ INLINE _DIFF _LINES _KEY ] [ inlineIndex ] ) . not . toEqual ( atInlineIndex ) ;
2018-11-08 19:23:39 +05:30
utils . removeMatchLine ( diffFile , lineNumbers , true ) ;
2018-12-13 13:39:08 +05:30
2021-02-22 17:27:13 +05:30
expect ( diffFile [ INLINE _DIFF _LINES _KEY ] [ inlineIndex + 1 ] ) . not . toEqual ( atInlineIndex ) ;
2018-11-08 19:23:39 +05:30
} ) ;
} ) ;
describe ( 'addContextLines' , ( ) => {
2021-02-22 17:27:13 +05:30
it ( ` should add context lines ` , ( ) => {
const diffFile = getDiffFileMock ( ) ;
const inlineLines = diffFile [ INLINE _DIFF _LINES _KEY ] ;
const lineNumbers = { oldLineNumber : 3 , newLineNumber : 5 } ;
const contextLines = [ { lineNumber : 42 , line _code : '123' } ] ;
const options = { inlineLines , contextLines , lineNumbers } ;
const inlineIndex = utils . findIndexInInlineLines ( inlineLines , lineNumbers ) ;
2020-04-08 14:13:33 +05:30
2021-02-22 17:27:13 +05:30
utils . addContextLines ( options ) ;
2020-04-08 14:13:33 +05:30
2021-02-22 17:27:13 +05:30
expect ( inlineLines [ inlineIndex ] ) . toEqual ( contextLines [ 0 ] ) ;
} ) ;
2019-07-07 11:18:12 +05:30
2021-02-22 17:27:13 +05:30
it ( ` should add context lines properly with bottom parameter ` , ( ) => {
const diffFile = getDiffFileMock ( ) ;
const inlineLines = diffFile [ INLINE _DIFF _LINES _KEY ] ;
const lineNumbers = { oldLineNumber : 3 , newLineNumber : 5 } ;
const contextLines = [ { lineNumber : 42 , line _code : '123' } ] ;
const options = {
inlineLines ,
contextLines ,
lineNumbers ,
bottom : true ,
} ;
2020-04-08 14:13:33 +05:30
2021-02-22 17:27:13 +05:30
utils . addContextLines ( options ) ;
2020-04-08 14:13:33 +05:30
2021-02-22 17:27:13 +05:30
expect ( inlineLines [ inlineLines . length - 1 ] ) . toEqual ( contextLines [ 0 ] ) ;
2018-11-08 19:23:39 +05:30
} ) ;
} ) ;
describe ( 'getNoteFormData' , ( ) => {
it ( 'should properly create note form data' , ( ) => {
const diffFile = getDiffFileMock ( ) ;
noteableDataMock . targetType = MERGE _REQUEST _NOTEABLE _TYPE ;
const options = {
note : 'Hello world!' ,
noteableData : noteableDataMock ,
noteableType : MERGE _REQUEST _NOTEABLE _TYPE ,
diffFile ,
noteTargetLine : {
2019-02-15 15:39:39 +05:30
line _code : '1c497fbb3a46b78edf04cc2a2fa33f67e3ffbe2a_1_3' ,
meta _data : null ,
new _line : 3 ,
old _line : 1 ,
2018-11-08 19:23:39 +05:30
} ,
linePosition : LINE _POSITION _LEFT ,
2021-12-07 22:27:20 +05:30
lineRange : { start : { line _code : 'abc_1_1' } , end : { line _code : 'abc_2_2' } } ,
2018-11-08 19:23:39 +05:30
} ;
const position = JSON . stringify ( {
2019-02-15 15:39:39 +05:30
base _sha : diffFile . diff _refs . base _sha ,
start _sha : diffFile . diff _refs . start _sha ,
head _sha : diffFile . diff _refs . head _sha ,
old _path : diffFile . old _path ,
new _path : diffFile . new _path ,
2018-11-08 19:23:39 +05:30
position _type : TEXT _DIFF _POSITION _TYPE ,
2019-02-15 15:39:39 +05:30
old _line : options . noteTargetLine . old _line ,
new _line : options . noteTargetLine . new _line ,
2020-06-23 00:09:42 +05:30
line _range : options . lineRange ,
2018-11-08 19:23:39 +05:30
} ) ;
const postData = {
view : options . diffViewType ,
line _type : options . linePosition === LINE _POSITION _RIGHT ? NEW _LINE _TYPE : OLD _LINE _TYPE ,
2019-02-15 15:39:39 +05:30
merge _request _diff _head _sha : diffFile . diff _refs . head _sha ,
2018-11-08 19:23:39 +05:30
in _reply _to _discussion _id : '' ,
note _project _id : '' ,
target _type : options . noteableType ,
target _id : options . noteableData . id ,
2018-12-05 23:21:45 +05:30
return _discussion : true ,
2018-11-08 19:23:39 +05:30
note : {
noteable _type : options . noteableType ,
noteable _id : options . noteableData . id ,
2019-02-15 15:39:39 +05:30
commit _id : undefined ,
2018-11-08 19:23:39 +05:30
type : DIFF _NOTE _TYPE ,
2019-02-15 15:39:39 +05:30
line _code : options . noteTargetLine . line _code ,
2018-11-08 19:23:39 +05:30
note : options . note ,
position ,
} ,
} ;
expect ( utils . getNoteFormData ( options ) ) . toEqual ( {
endpoint : options . noteableData . create _note _path ,
data : postData ,
} ) ;
} ) ;
2018-12-05 23:21:45 +05:30
it ( 'should create legacy note form data' , ( ) => {
const diffFile = getDiffFileMock ( ) ;
2019-02-15 15:39:39 +05:30
delete diffFile . diff _refs . start _sha ;
delete diffFile . diff _refs . head _sha ;
2018-12-05 23:21:45 +05:30
noteableDataMock . targetType = MERGE _REQUEST _NOTEABLE _TYPE ;
const options = {
note : 'Hello world!' ,
noteableData : noteableDataMock ,
noteableType : MERGE _REQUEST _NOTEABLE _TYPE ,
diffFile ,
noteTargetLine : {
2019-02-15 15:39:39 +05:30
line _code : '1c497fbb3a46b78edf04cc2a2fa33f67e3ffbe2a_1_3' ,
meta _data : null ,
new _line : 3 ,
old _line : 1 ,
2018-12-05 23:21:45 +05:30
} ,
linePosition : LINE _POSITION _LEFT ,
} ;
const position = JSON . stringify ( {
2019-02-15 15:39:39 +05:30
base _sha : diffFile . diff _refs . base _sha ,
2018-12-05 23:21:45 +05:30
start _sha : undefined ,
head _sha : undefined ,
2019-02-15 15:39:39 +05:30
old _path : diffFile . old _path ,
new _path : diffFile . new _path ,
2018-12-05 23:21:45 +05:30
position _type : TEXT _DIFF _POSITION _TYPE ,
2019-02-15 15:39:39 +05:30
old _line : options . noteTargetLine . old _line ,
new _line : options . noteTargetLine . new _line ,
2018-12-05 23:21:45 +05:30
} ) ;
const postData = {
view : options . diffViewType ,
line _type : options . linePosition === LINE _POSITION _RIGHT ? NEW _LINE _TYPE : OLD _LINE _TYPE ,
merge _request _diff _head _sha : undefined ,
in _reply _to _discussion _id : '' ,
note _project _id : '' ,
target _type : options . noteableType ,
target _id : options . noteableData . id ,
return _discussion : true ,
note : {
noteable _type : options . noteableType ,
noteable _id : options . noteableData . id ,
2019-02-15 15:39:39 +05:30
commit _id : undefined ,
2018-12-05 23:21:45 +05:30
type : LEGACY _DIFF _NOTE _TYPE ,
2019-02-15 15:39:39 +05:30
line _code : options . noteTargetLine . line _code ,
2018-12-05 23:21:45 +05:30
note : options . note ,
position ,
} ,
} ;
expect ( utils . getNoteFormData ( options ) ) . toEqual ( {
endpoint : options . noteableData . create _note _path ,
data : postData ,
} ) ;
} ) ;
2018-11-08 19:23:39 +05:30
} ) ;
describe ( 'addLineReferences' , ( ) => {
const lineNumbers = { oldLineNumber : 3 , newLineNumber : 4 } ;
it ( 'should add correct line references when bottom set to true' , ( ) => {
const lines = [ { type : null } , { type : MATCH _LINE _TYPE } ] ;
const linesWithReferences = utils . addLineReferences ( lines , lineNumbers , true ) ;
2019-02-15 15:39:39 +05:30
expect ( linesWithReferences [ 0 ] . old _line ) . toEqual ( lineNumbers . oldLineNumber + 1 ) ;
expect ( linesWithReferences [ 0 ] . new _line ) . toEqual ( lineNumbers . newLineNumber + 1 ) ;
expect ( linesWithReferences [ 1 ] . meta _data . old _pos ) . toEqual ( 4 ) ;
expect ( linesWithReferences [ 1 ] . meta _data . new _pos ) . toEqual ( 5 ) ;
2018-11-08 19:23:39 +05:30
} ) ;
it ( 'should add correct line references when bottom falsy' , ( ) => {
const lines = [ { type : null } , { type : MATCH _LINE _TYPE } , { type : null } ] ;
const linesWithReferences = utils . addLineReferences ( lines , lineNumbers ) ;
2019-02-15 15:39:39 +05:30
expect ( linesWithReferences [ 0 ] . old _line ) . toEqual ( 0 ) ;
expect ( linesWithReferences [ 0 ] . new _line ) . toEqual ( 1 ) ;
expect ( linesWithReferences [ 1 ] . meta _data . old _pos ) . toEqual ( 2 ) ;
expect ( linesWithReferences [ 1 ] . meta _data . new _pos ) . toEqual ( 3 ) ;
2018-11-08 19:23:39 +05:30
} ) ;
2019-10-12 21:52:04 +05:30
it ( 'should add correct line references when isExpandDown is true' , ( ) => {
const lines = [ { type : null } , { type : MATCH _LINE _TYPE } ] ;
const linesWithReferences = utils . addLineReferences ( lines , lineNumbers , false , true , {
old _line : 10 ,
new _line : 11 ,
} ) ;
expect ( linesWithReferences [ 1 ] . meta _data . old _pos ) . toEqual ( 10 ) ;
expect ( linesWithReferences [ 1 ] . meta _data . new _pos ) . toEqual ( 11 ) ;
} ) ;
2018-11-08 19:23:39 +05:30
} ) ;
describe ( 'trimFirstCharOfLineContent' , ( ) => {
it ( 'trims the line when it starts with a space' , ( ) => {
2021-04-17 20:07:23 +05:30
// eslint-disable-next-line import/no-deprecated
2019-02-15 15:39:39 +05:30
expect ( utils . trimFirstCharOfLineContent ( { rich _text : ' diff' } ) ) . toEqual ( {
rich _text : 'diff' ,
2018-11-20 20:47:30 +05:30
} ) ;
2018-11-08 19:23:39 +05:30
} ) ;
it ( 'trims the line when it starts with a +' , ( ) => {
2021-04-17 20:07:23 +05:30
// eslint-disable-next-line import/no-deprecated
2019-02-15 15:39:39 +05:30
expect ( utils . trimFirstCharOfLineContent ( { rich _text : '+diff' } ) ) . toEqual ( {
rich _text : 'diff' ,
2018-11-20 20:47:30 +05:30
} ) ;
2018-11-08 19:23:39 +05:30
} ) ;
it ( 'trims the line when it starts with a -' , ( ) => {
2021-04-17 20:07:23 +05:30
// eslint-disable-next-line import/no-deprecated
2019-02-15 15:39:39 +05:30
expect ( utils . trimFirstCharOfLineContent ( { rich _text : '-diff' } ) ) . toEqual ( {
rich _text : 'diff' ,
2018-11-20 20:47:30 +05:30
} ) ;
2018-11-08 19:23:39 +05:30
} ) ;
it ( 'does not trims the line when it starts with a letter' , ( ) => {
2021-04-17 20:07:23 +05:30
// eslint-disable-next-line import/no-deprecated
2019-02-15 15:39:39 +05:30
expect ( utils . trimFirstCharOfLineContent ( { rich _text : 'diff' } ) ) . toEqual ( {
rich _text : 'diff' ,
2018-11-20 20:47:30 +05:30
} ) ;
2018-11-08 19:23:39 +05:30
} ) ;
it ( 'does not modify the provided object' , ( ) => {
const lineObj = {
2019-02-15 15:39:39 +05:30
rich _text : ' diff' ,
2018-11-08 19:23:39 +05:30
} ;
2021-04-17 20:07:23 +05:30
// eslint-disable-next-line import/no-deprecated
2018-11-08 19:23:39 +05:30
utils . trimFirstCharOfLineContent ( lineObj ) ;
2018-12-13 13:39:08 +05:30
2019-03-02 22:35:43 +05:30
expect ( lineObj ) . toEqual ( { rich _text : ' diff' } ) ;
2018-11-08 19:23:39 +05:30
} ) ;
it ( 'handles a undefined or null parameter' , ( ) => {
2021-04-17 20:07:23 +05:30
// eslint-disable-next-line import/no-deprecated
2019-03-02 22:35:43 +05:30
expect ( utils . trimFirstCharOfLineContent ( ) ) . toEqual ( { } ) ;
2018-11-20 20:47:30 +05:30
} ) ;
} ) ;
2020-05-24 23:13:21 +05:30
describe ( 'prepareLineForRenamedFile' , ( ) => {
const diffFile = {
file _hash : 'file-hash' ,
2023-01-13 00:05:48 +05:30
brokenSymlink : false ,
renamed _file : false ,
added _lines : 1 ,
removed _lines : 1 ,
2020-05-24 23:13:21 +05:30
} ;
const lineIndex = 4 ;
const sourceLine = {
2023-01-13 00:05:48 +05:30
line _code : 'abc' ,
2020-05-24 23:13:21 +05:30
foo : 'test' ,
rich _text : ' <p>rich</p>' , // Note the leading space
} ;
const correctLine = {
foo : 'test' ,
line _code : 'file-hash_5_5' ,
old _line : 5 ,
new _line : 5 ,
rich _text : '<p>rich</p>' , // Note no leading space
discussionsExpanded : true ,
discussions : [ ] ,
hasForm : false ,
text : undefined ,
alreadyPrepared : true ,
2023-01-13 00:05:48 +05:30
commentsDisabled : false ,
problems : {
brokenLineCode : false ,
brokenSymlink : false ,
fileOnlyMoved : false ,
} ,
2020-05-24 23:13:21 +05:30
} ;
let preppedLine ;
beforeEach ( ( ) => {
preppedLine = utils . prepareLineForRenamedFile ( {
diffViewType : INLINE _DIFF _VIEW _TYPE ,
line : sourceLine ,
index : lineIndex ,
diffFile ,
} ) ;
} ) ;
it ( 'copies over the original line object to the new prepared line' , ( ) => {
expect ( preppedLine ) . toEqual (
expect . objectContaining ( {
foo : correctLine . foo ,
rich _text : correctLine . rich _text ,
} ) ,
) ;
} ) ;
it ( 'correctly sets the old and new lines, plus a line code' , ( ) => {
expect ( preppedLine . old _line ) . toEqual ( correctLine . old _line ) ;
expect ( preppedLine . new _line ) . toEqual ( correctLine . new _line ) ;
expect ( preppedLine . line _code ) . toEqual ( correctLine . line _code ) ;
} ) ;
it ( 'returns a single object with the correct structure for `inline` lines' , ( ) => {
expect ( preppedLine ) . toEqual ( correctLine ) ;
} ) ;
2020-10-24 23:57:45 +05:30
it . each `
2023-01-13 00:05:48 +05:30
brokenSymlink | renamed | added | removed | lineCode | commentsDisabled
$ { false } | $ { false } | $ { 0 } | $ { 0 } | $ { 'a' } | $ { false }
$ { { } } | $ { false } | $ { 1 } | $ { 1 } | $ { 'a' } | $ { true }
$ { 'truthy' } | $ { false } | $ { 1 } | $ { 1 } | $ { 'a' } | $ { true }
$ { false } | $ { true } | $ { 1 } | $ { 1 } | $ { 'a' } | $ { false }
$ { false } | $ { true } | $ { 1 } | $ { 0 } | $ { 'a' } | $ { false }
$ { false } | $ { true } | $ { 0 } | $ { 1 } | $ { 'a' } | $ { false }
$ { false } | $ { true } | $ { 0 } | $ { 0 } | $ { 'a' } | $ { true }
2020-10-24 23:57:45 +05:30
` (
2023-01-13 00:05:48 +05:30
"properly sets a line's `commentsDisabled` to '$commentsDisabled' for file and line settings { brokenSymlink: $brokenSymlink, renamed: $renamed, added: $added, removed: $removed, line_code: $lineCode }" ,
( { brokenSymlink , renamed , added , removed , lineCode , commentsDisabled } ) => {
const line = {
... sourceLine ,
line _code : lineCode ,
} ;
const file = {
... diffFile ,
brokenSymlink ,
renamed _file : renamed ,
added _lines : added ,
removed _lines : removed ,
} ;
const preparedLine = utils . prepareLineForRenamedFile ( {
2020-10-24 23:57:45 +05:30
index : lineIndex ,
2023-01-13 00:05:48 +05:30
diffFile : file ,
line ,
2020-10-24 23:57:45 +05:30
} ) ;
2023-01-13 00:05:48 +05:30
expect ( preparedLine . commentsDisabled ) . toBe ( commentsDisabled ) ;
2020-10-24 23:57:45 +05:30
} ,
) ;
2020-05-24 23:13:21 +05:30
} ) ;
2018-11-20 20:47:30 +05:30
describe ( 'prepareDiffData' , ( ) => {
2020-06-23 00:09:42 +05:30
describe ( 'for regular diff files' , ( ) => {
let mock ;
let preparedDiff ;
let splitInlineDiff ;
let splitParallelDiff ;
let completedDiff ;
beforeEach ( ( ) => {
mock = getDiffFileMock ( ) ;
preparedDiff = { diff _files : [ mock ] } ;
splitInlineDiff = {
2021-02-22 17:27:13 +05:30
diff _files : [ { ... mock } ] ,
2020-06-23 00:09:42 +05:30
} ;
splitParallelDiff = {
2021-02-22 17:27:13 +05:30
diff _files : [ { ... mock , [ INLINE _DIFF _LINES _KEY ] : undefined } ] ,
2020-06-23 00:09:42 +05:30
} ;
completedDiff = {
2021-02-22 17:27:13 +05:30
diff _files : [ { ... mock , [ INLINE _DIFF _LINES _KEY ] : undefined } ] ,
2020-06-23 00:09:42 +05:30
} ;
2019-02-15 15:39:39 +05:30
2021-02-22 17:27:13 +05:30
preparedDiff . diff _files = utils . prepareDiffData ( { diff : preparedDiff } ) ;
splitInlineDiff . diff _files = utils . prepareDiffData ( { diff : splitInlineDiff } ) ;
splitParallelDiff . diff _files = utils . prepareDiffData ( { diff : splitParallelDiff } ) ;
completedDiff . diff _files = utils . prepareDiffData ( {
diff : completedDiff ,
priorFiles : [ mock ] ,
} ) ;
2020-06-23 00:09:42 +05:30
} ) ;
2020-03-13 15:44:24 +05:30
2020-06-23 00:09:42 +05:30
it ( 'sets the renderIt and collapsed attribute on files' , ( ) => {
2021-02-22 17:27:13 +05:30
const checkLine = preparedDiff . diff _files [ 0 ] [ INLINE _DIFF _LINES _KEY ] [ 0 ] ;
2018-11-20 20:47:30 +05:30
2020-06-23 00:09:42 +05:30
expect ( checkLine . discussions . length ) . toBe ( 0 ) ;
expect ( checkLine ) . not . toHaveAttr ( 'text' ) ;
const firstChar = checkLine . rich _text . charAt ( 0 ) ;
2018-12-13 13:39:08 +05:30
2020-06-23 00:09:42 +05:30
expect ( firstChar ) . not . toBe ( ' ' ) ;
expect ( firstChar ) . not . toBe ( '+' ) ;
expect ( firstChar ) . not . toBe ( '-' ) ;
2018-12-13 13:39:08 +05:30
2022-08-27 11:52:29 +05:30
expect ( preparedDiff . diff _files [ 0 ] . renderIt ) . toBe ( true ) ;
expect ( preparedDiff . diff _files [ 0 ] . collapsed ) . toBe ( false ) ;
2020-06-23 00:09:42 +05:30
} ) ;
2018-11-20 20:47:30 +05:30
2020-06-23 00:09:42 +05:30
it ( 'guarantees an empty array for both diff styles' , ( ) => {
2021-02-22 17:27:13 +05:30
expect ( splitInlineDiff . diff _files [ 0 ] [ INLINE _DIFF _LINES _KEY ] . length ) . toBeGreaterThan ( 0 ) ;
expect ( splitParallelDiff . diff _files [ 0 ] [ INLINE _DIFF _LINES _KEY ] . length ) . toEqual ( 0 ) ;
2020-06-23 00:09:42 +05:30
} ) ;
2020-03-13 15:44:24 +05:30
2020-06-23 00:09:42 +05:30
it ( 'merges existing diff files with newly loaded diff files to ensure split diffs are eventually completed' , ( ) => {
expect ( completedDiff . diff _files . length ) . toEqual ( 1 ) ;
2021-02-22 17:27:13 +05:30
expect ( completedDiff . diff _files [ 0 ] [ INLINE _DIFF _LINES _KEY ] . length ) . toBeGreaterThan ( 0 ) ;
2020-06-23 00:09:42 +05:30
} ) ;
2020-03-13 15:44:24 +05:30
2020-06-23 00:09:42 +05:30
it ( 'leaves files in the existing state' , ( ) => {
const priorFiles = [ mock ] ;
const fakeNewFile = {
... mock ,
content _sha : 'ABC' ,
file _hash : 'DEF' ,
} ;
2021-02-22 17:27:13 +05:30
const updatedFilesList = utils . prepareDiffData ( {
diff : { diff _files : [ fakeNewFile ] } ,
priorFiles ,
} ) ;
2020-03-13 15:44:24 +05:30
2020-06-23 00:09:42 +05:30
expect ( updatedFilesList ) . toEqual ( [ mock , fakeNewFile ] ) ;
} ) ;
2020-03-13 15:44:24 +05:30
2020-06-23 00:09:42 +05:30
it ( 'completes an existing split diff without overwriting existing diffs' , ( ) => {
// The current state has a file that has only loaded inline lines
2021-02-22 17:27:13 +05:30
const priorFiles = [ { ... mock } ] ;
2020-06-23 00:09:42 +05:30
// The next (batch) load loads two files: the other half of that file, and a new file
const fakeBatch = [
2021-02-22 17:27:13 +05:30
{ ... mock , [ INLINE _DIFF _LINES _KEY ] : undefined } ,
{ ... mock , [ INLINE _DIFF _LINES _KEY ] : undefined , content _sha : 'ABC' , file _hash : 'DEF' } ,
2020-06-23 00:09:42 +05:30
] ;
2021-02-22 17:27:13 +05:30
const updatedFilesList = utils . prepareDiffData ( {
diff : { diff _files : fakeBatch } ,
priorFiles ,
} ) ;
2020-06-23 00:09:42 +05:30
expect ( updatedFilesList ) . toEqual ( [
mock ,
expect . objectContaining ( {
content _sha : 'ABC' ,
file _hash : 'DEF' ,
} ) ,
] ) ;
} ) ;
2020-10-24 23:57:45 +05:30
it ( 'adds the `.brokenSymlink` property to each diff file' , ( ) => {
2021-03-08 18:12:59 +05:30
preparedDiff . diff _files . forEach ( ( file ) => {
2023-01-13 00:05:48 +05:30
expect ( file ) . toHaveProperty ( 'brokenSymlink' , false ) ;
2020-10-24 23:57:45 +05:30
} ) ;
} ) ;
it ( "copies the diff file's `.brokenSymlink` value to each of that file's child lines" , ( ) => {
const lines = [
... preparedDiff . diff _files ,
... splitInlineDiff . diff _files ,
... splitParallelDiff . diff _files ,
... completedDiff . diff _files ,
2021-03-08 18:12:59 +05:30
] . flatMap ( ( file ) => [ ... file [ INLINE _DIFF _LINES _KEY ] ] ) ;
2020-10-24 23:57:45 +05:30
2021-03-08 18:12:59 +05:30
lines . forEach ( ( line ) => {
2023-01-13 00:05:48 +05:30
expect ( line . problems . brokenSymlink ) . toBe ( false ) ;
2020-10-24 23:57:45 +05:30
} ) ;
} ) ;
2020-03-13 15:44:24 +05:30
} ) ;
2020-06-23 00:09:42 +05:30
describe ( 'for diff metadata' , ( ) => {
let mock ;
let preparedDiffFiles ;
beforeEach ( ( ) => {
mock = getDiffMetadataMock ( ) ;
2021-02-22 17:27:13 +05:30
preparedDiffFiles = utils . prepareDiffData ( { diff : mock , meta : true } ) ;
2020-06-23 00:09:42 +05:30
} ) ;
it ( 'sets the renderIt and collapsed attribute on files' , ( ) => {
2022-08-27 11:52:29 +05:30
expect ( preparedDiffFiles [ 0 ] . renderIt ) . toBe ( true ) ;
expect ( preparedDiffFiles [ 0 ] . collapsed ) . toBeUndefined ( ) ;
2020-06-23 00:09:42 +05:30
} ) ;
it ( 'guarantees an empty array of lines for both diff styles' , ( ) => {
2021-02-22 17:27:13 +05:30
expect ( preparedDiffFiles [ 0 ] [ INLINE _DIFF _LINES _KEY ] . length ) . toEqual ( 0 ) ;
2020-06-23 00:09:42 +05:30
} ) ;
it ( 'leaves files in the existing state' , ( ) => {
const fileMock = getDiffFileMock ( ) ;
const metaData = getDiffMetadataMock ( ) ;
const priorFiles = [ fileMock ] ;
2021-02-22 17:27:13 +05:30
const updatedFilesList = utils . prepareDiffData ( { diff : metaData , priorFiles , meta : true } ) ;
2020-06-23 00:09:42 +05:30
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 } ] ;
2021-02-22 17:27:13 +05:30
const updatedFilesList = utils . prepareDiffData ( { diff : metaMock , priorFiles , meta : true } ) ;
2020-06-23 00:09:42 +05:30
expect ( updatedFilesList ) . toEqual ( [
fileMock ,
{
... metaMock . diff _files [ 0 ] ,
2021-02-22 17:27:13 +05:30
[ INLINE _DIFF _LINES _KEY ] : [ ] ,
2020-06-23 00:09:42 +05:30
} ,
] ) ;
} ) ;
2020-10-24 23:57:45 +05:30
it ( 'adds the `.brokenSymlink` property to each meta diff file' , ( ) => {
2021-03-08 18:12:59 +05:30
preparedDiffFiles . forEach ( ( file ) => {
2020-10-24 23:57:45 +05:30
expect ( file ) . toMatchObject ( { brokenSymlink : false } ) ;
} ) ;
} ) ;
2020-03-13 15:44:24 +05:30
} ) ;
2018-11-20 20:47:30 +05:30
} ) ;
describe ( 'isDiscussionApplicableToLine' , ( ) => {
const diffPosition = {
baseSha : 'ed13df29948c41ba367caa757ab3ec4892509910' ,
headSha : 'b921914f9a834ac47e6fd9420f78db0f83559130' ,
newLine : null ,
newPath : '500-lines-4.txt' ,
oldLine : 5 ,
oldPath : '500-lines-4.txt' ,
startSha : 'ed13df29948c41ba367caa757ab3ec4892509910' ,
} ;
const wrongDiffPosition = {
baseSha : 'wrong' ,
headSha : 'wrong' ,
newLine : null ,
newPath : '500-lines-4.txt' ,
oldLine : 5 ,
oldPath : '500-lines-4.txt' ,
startSha : 'wrong' ,
} ;
const discussions = {
upToDateDiscussion1 : {
original _position : diffPosition ,
position : wrongDiffPosition ,
} ,
outDatedDiscussion1 : {
original _position : wrongDiffPosition ,
position : wrongDiffPosition ,
} ,
} ;
2020-05-24 23:13:21 +05:30
// When multi line comments are fully implemented `line_code` will be
// included in all requests. Until then we need to ensure the logic does
// not change when it is included only in the "comparison" argument.
2021-12-07 22:27:20 +05:30
const lineRange = { start : { line _code : 'abc_1_1' } , end : { line _code : 'abc_1_2' } } ;
2020-05-24 23:13:21 +05:30
2018-11-20 20:47:30 +05:30
it ( 'returns true when the discussion is up to date' , ( ) => {
expect (
2018-12-05 23:21:45 +05:30
utils . isDiscussionApplicableToLine ( {
discussion : discussions . upToDateDiscussion1 ,
2020-05-24 23:13:21 +05:30
diffPosition : { ... diffPosition , line _range : lineRange } ,
2018-12-05 23:21:45 +05:30
latestDiff : true ,
} ) ,
2018-11-20 20:47:30 +05:30
) . toBe ( true ) ;
} ) ;
it ( 'returns false when the discussion is not up to date' , ( ) => {
expect (
2018-12-05 23:21:45 +05:30
utils . isDiscussionApplicableToLine ( {
discussion : discussions . outDatedDiscussion1 ,
2020-05-24 23:13:21 +05:30
diffPosition : { ... diffPosition , line _range : lineRange } ,
2018-12-05 23:21:45 +05:30
latestDiff : true ,
} ) ,
) . toBe ( false ) ;
} ) ;
it ( 'returns true when line codes match and discussion does not contain position and is not active' , ( ) => {
const discussion = { ... discussions . outDatedDiscussion1 , line _code : 'ABC_1' , active : false } ;
delete discussion . original _position ;
delete discussion . position ;
expect (
utils . isDiscussionApplicableToLine ( {
discussion ,
diffPosition : {
... diffPosition ,
lineCode : 'ABC_1' ,
2020-05-24 23:13:21 +05:30
line _range : lineRange ,
2018-12-05 23:21:45 +05:30
} ,
latestDiff : true ,
} ) ,
2018-11-20 20:47:30 +05:30
) . toBe ( false ) ;
2018-11-08 19:23:39 +05:30
} ) ;
2018-12-05 23:21:45 +05:30
it ( 'returns true when line codes match and discussion does not contain position and is active' , ( ) => {
const discussion = { ... discussions . outDatedDiscussion1 , line _code : 'ABC_1' , active : true } ;
delete discussion . original _position ;
delete discussion . position ;
expect (
utils . isDiscussionApplicableToLine ( {
discussion ,
diffPosition : {
... diffPosition ,
2019-02-15 15:39:39 +05:30
line _code : 'ABC_1' ,
2020-05-24 23:13:21 +05:30
line _range : lineRange ,
2018-12-05 23:21:45 +05:30
} ,
latestDiff : true ,
} ) ,
) . toBe ( true ) ;
} ) ;
it ( 'returns false when not latest diff' , ( ) => {
const discussion = { ... discussions . outDatedDiscussion1 , line _code : 'ABC_1' , active : true } ;
delete discussion . original _position ;
delete discussion . position ;
expect (
utils . isDiscussionApplicableToLine ( {
discussion ,
diffPosition : {
... diffPosition ,
lineCode : 'ABC_1' ,
2020-05-24 23:13:21 +05:30
line _range : lineRange ,
2018-12-05 23:21:45 +05:30
} ,
latestDiff : false ,
} ) ,
) . toBe ( false ) ;
} ) ;
} ) ;
2019-02-15 15:39:39 +05:30
describe ( 'getDiffMode' , ( ) => {
it ( 'returns mode when matched in file' , ( ) => {
expect (
utils . getDiffMode ( {
renamed _file : true ,
} ) ,
) . toBe ( 'renamed' ) ;
} ) ;
it ( 'returns mode_changed if key has no match' , ( ) => {
expect (
utils . getDiffMode ( {
2019-07-07 11:18:12 +05:30
viewer : { name : 'mode_changed' } ,
2019-02-15 15:39:39 +05:30
} ) ,
) . toBe ( 'mode_changed' ) ;
} ) ;
it ( 'defaults to replaced' , ( ) => {
expect ( utils . getDiffMode ( { } ) ) . toBe ( 'replaced' ) ;
} ) ;
} ) ;
2019-03-02 22:35:43 +05:30
2019-07-07 11:18:12 +05:30
describe ( 'convertExpandLines' , ( ) => {
it ( 'converts expanded lines to normal lines' , ( ) => {
const diffLines = [
{
type : 'match' ,
old _line : 1 ,
new _line : 1 ,
} ,
{
type : '' ,
old _line : 2 ,
new _line : 2 ,
} ,
] ;
const lines = utils . convertExpandLines ( {
diffLines ,
data : [ { text : 'expanded' } ] ,
typeKey : 'type' ,
oldLineKey : 'old_line' ,
newLineKey : 'new_line' ,
mapLine : ( { line , oldLine , newLine } ) => ( {
... line ,
old _line : oldLine ,
new _line : newLine ,
} ) ,
} ) ;
expect ( lines ) . toEqual ( [
{
text : 'expanded' ,
new _line : 1 ,
old _line : 1 ,
discussions : [ ] ,
hasForm : false ,
} ,
{
type : '' ,
old _line : 2 ,
new _line : 2 ,
} ,
] ) ;
} ) ;
} ) ;
2020-07-28 23:09:34 +05:30
2020-11-24 15:15:51 +05:30
describe ( 'isAdded' , ( ) => {
it . each `
type | expected
$ { 'new' } | $ { true }
$ { 'new-nonewline' } | $ { true }
$ { 'old' } | $ { false }
` ('returns $ expected when type is $ type', ({ type, expected }) => {
expect ( utils . isAdded ( { type } ) ) . toBe ( expected ) ;
} ) ;
} ) ;
describe ( 'isRemoved' , ( ) => {
it . each `
type | expected
$ { 'old' } | $ { true }
$ { 'old-nonewline' } | $ { true }
$ { 'new' } | $ { false }
` ('returns $ expected when type is $ type', ({ type, expected }) => {
expect ( utils . isRemoved ( { type } ) ) . toBe ( expected ) ;
} ) ;
} ) ;
describe ( 'isUnchanged' , ( ) => {
it . each `
type | expected
$ { null } | $ { true }
$ { 'new' } | $ { false }
$ { 'old' } | $ { false }
` ('returns $ expected when type is $ type', ({ type, expected }) => {
expect ( utils . isUnchanged ( { type } ) ) . toBe ( expected ) ;
} ) ;
} ) ;
describe ( 'isMeta' , ( ) => {
it . each `
type | expected
$ { 'match' } | $ { true }
$ { 'new-nonewline' } | $ { true }
$ { 'old-nonewline' } | $ { true }
$ { 'new' } | $ { false }
` ('returns $ expected when type is $ type', ({ type, expected }) => {
expect ( utils . isMeta ( { type } ) ) . toBe ( expected ) ;
} ) ;
} ) ;
2021-03-08 18:12:59 +05:30
describe ( 'isConflictMarker' , ( ) => {
it . each `
type | expected
$ { 'conflict_marker_our' } | $ { true }
$ { 'conflict_marker_their' } | $ { true }
$ { 'conflict_their' } | $ { false }
$ { 'conflict_our' } | $ { false }
` ('returns $ expected when type is $ type', ({ type, expected }) => {
expect ( utils . isConflictMarker ( { type } ) ) . toBe ( expected ) ;
} ) ;
} ) ;
describe ( 'isConflictOur' , ( ) => {
it . each `
type | expected
$ { 'conflict_marker_our' } | $ { false }
$ { 'conflict_marker_their' } | $ { false }
$ { 'conflict_their' } | $ { false }
$ { 'conflict_our' } | $ { true }
` ('returns $ expected when type is $ type', ({ type, expected }) => {
expect ( utils . isConflictOur ( { type } ) ) . toBe ( expected ) ;
} ) ;
} ) ;
describe ( 'isConflictTheir' , ( ) => {
it . each `
type | expected
$ { 'conflict_marker_our' } | $ { false }
$ { 'conflict_marker_their' } | $ { false }
$ { 'conflict_their' } | $ { true }
$ { 'conflict_our' } | $ { false }
` ('returns $ expected when type is $ type', ({ type, expected }) => {
expect ( utils . isConflictTheir ( { type } ) ) . toBe ( expected ) ;
} ) ;
} ) ;
2020-11-24 15:15:51 +05:30
describe ( 'parallelizeDiffLines' , ( ) => {
it ( 'converts inline diff lines to parallel diff lines' , ( ) => {
const file = getDiffFileMock ( ) ;
2021-03-08 18:12:59 +05:30
expect ( utils . parallelizeDiffLines ( file [ INLINE _DIFF _LINES _KEY ] ) ) . toMatchObject (
2020-11-24 15:15:51 +05:30
file . parallel _diff _lines ,
) ;
} ) ;
2021-01-29 00:20:46 +05:30
2021-03-08 18:12:59 +05:30
it ( 'converts conflicted diffs line' , ( ) => {
const lines = [
{ type : 'new' } ,
{ type : 'conflict_marker_our' } ,
{ type : 'conflict_our' } ,
{ type : 'conflict_marker' } ,
{ type : 'conflict_their' } ,
{ type : 'conflict_marker_their' } ,
] ;
expect ( utils . parallelizeDiffLines ( lines ) ) . toEqual ( [
{
left : null ,
right : {
chunk : 0 ,
type : 'new' ,
} ,
} ,
{
left : { chunk : 0 , type : 'conflict_marker_our' } ,
right : { chunk : 0 , type : 'conflict_marker_their' } ,
} ,
{
left : { chunk : 0 , type : 'conflict_our' } ,
right : { chunk : 0 , type : 'conflict_their' } ,
} ,
] ) ;
} ) ;
2021-02-22 17:27:13 +05:30
it ( 'converts inline diff lines' , ( ) => {
2021-01-29 00:20:46 +05:30
const file = getDiffFileMock ( ) ;
const files = utils . parallelizeDiffLines ( file . highlighted _diff _lines , true ) ;
2021-03-08 18:12:59 +05:30
expect ( files [ 5 ] . left ) . toMatchObject ( file . parallel _diff _lines [ 5 ] . left ) ;
2021-01-29 00:20:46 +05:30
expect ( files [ 5 ] . right ) . toBeNull ( ) ;
2021-03-08 18:12:59 +05:30
expect ( files [ 6 ] . left ) . toMatchObject ( file . parallel _diff _lines [ 5 ] . right ) ;
2021-02-22 17:27:13 +05:30
expect ( files [ 6 ] . right ) . toBeNull ( ) ;
2021-01-29 00:20:46 +05:30
} ) ;
2020-11-24 15:15:51 +05:30
} ) ;
2023-05-27 22:25:52 +05:30
describe ( 'isUrlHashNoteLink' , ( ) => {
it . each `
input | bool
$ { '#note_12345' } | $ { true }
$ { '#12345' } | $ { false }
$ { 'note_12345' } | $ { true }
$ { '12345' } | $ { false }
` ('returns $ bool for $ input', ({ bool, input }) => {
expect ( utils . isUrlHashNoteLink ( input ) ) . toBe ( bool ) ;
} ) ;
} ) ;
describe ( 'isUrlHashFileHeader' , ( ) => {
it . each `
input | bool
$ { '#diff-content-12345' } | $ { true }
$ { '#12345' } | $ { false }
$ { 'diff-content-12345' } | $ { true }
$ { '12345' } | $ { false }
` ('returns $ bool for $ input', ({ bool, input }) => {
expect ( utils . isUrlHashFileHeader ( input ) ) . toBe ( bool ) ;
} ) ;
} ) ;
describe ( 'parseUrlHashAsFileHash' , ( ) => {
it . each `
input | currentDiffId | resultId
$ { '#note_12345' } | $ { '1A2B3C' } | $ { '1A2B3C' }
$ { 'note_12345' } | $ { '1A2B3C' } | $ { '1A2B3C' }
$ { '#note_12345' } | $ { undefined } | $ { null }
$ { 'note_12345' } | $ { undefined } | $ { null }
$ { '#diff-content-12345' } | $ { undefined } | $ { '12345' }
$ { 'diff-content-12345' } | $ { undefined } | $ { '12345' }
$ { '#diff-content-12345' } | $ { '98765' } | $ { '12345' }
$ { 'diff-content-12345' } | $ { '98765' } | $ { '12345' }
$ { '#e334a2a10f036c00151a04cea7938a5d4213a818' } | $ { undefined } | $ { 'e334a2a10f036c00151a04cea7938a5d4213a818' }
$ { 'e334a2a10f036c00151a04cea7938a5d4213a818' } | $ { undefined } | $ { 'e334a2a10f036c00151a04cea7938a5d4213a818' }
$ { '#Z334a2a10f036c00151a04cea7938a5d4213a818' } | $ { undefined } | $ { null }
$ { 'Z334a2a10f036c00151a04cea7938a5d4213a818' } | $ { undefined } | $ { null }
` ('returns $ resultId for $ input and $ currentDiffId', ({ input, currentDiffId, resultId }) => {
expect ( utils . parseUrlHashAsFileHash ( input , currentDiffId ) ) . toBe ( resultId ) ;
} ) ;
} ) ;
describe ( 'markTreeEntriesLoaded' , ( ) => {
it . each `
desc | entries | loaded | outcome
$ { 'marks an existing entry as loaded' } | $ { { abc : { } } } | $ { [ { new _path : 'abc' } ] } | $ { { abc : { diffLoaded : true } } }
$ { 'does nothing if the new file is not found in the tree entries' } | $ { { abc : { } } } | $ { [ { new _path : 'def' } ] } | $ { { abc : { } } }
$ { 'leaves entries unmodified if they are not in the loaded files' } | $ { { abc : { } , def : { diffLoaded : true } , ghi : { } } } | $ { [ { new _path : 'ghi' } ] } | $ { { abc : { } , def : { diffLoaded : true } , ghi : { diffLoaded : true } } }
` (' $ desc', ({ entries, loaded, outcome }) => {
expect ( utils . markTreeEntriesLoaded ( { priorEntries : entries , loadedFiles : loaded } ) ) . toEqual (
outcome ,
) ;
} ) ;
} ) ;
2018-11-08 19:23:39 +05:30
} ) ;