2021-03-08 18:12:59 +05:30
import { getByTestId , fireEvent } from '@testing-library/dom' ;
2021-06-08 01:23:25 +05:30
import { shallowMount } from '@vue/test-utils' ;
import Vue from 'vue' ;
2021-01-29 00:20:46 +05:30
import Vuex from 'vuex' ;
import DiffRow from '~/diffs/components/diff_row.vue' ;
2021-03-08 18:12:59 +05:30
import { mapParallel } from '~/diffs/components/diff_row_utils' ;
2021-03-11 19:13:27 +05:30
import diffsModule from '~/diffs/store/modules' ;
2021-04-29 21:17:54 +05:30
import { findInteropAttributes } from '../find_interop_attributes' ;
2021-03-11 19:13:27 +05:30
import diffFileMockData from '../mock_data/diff_file' ;
2021-01-29 00:20:46 +05:30
2021-09-30 23:02:18 +05:30
const showCommentForm = jest . fn ( ) ;
const enterdragging = jest . fn ( ) ;
const stopdragging = jest . fn ( ) ;
const setHighlightedRow = jest . fn ( ) ;
let wrapper ;
2021-01-29 00:20:46 +05:30
describe ( 'DiffRow' , ( ) => {
const testLines = [
{
left : { old _line : 1 , discussions : [ ] } ,
right : { new _line : 1 , discussions : [ ] } ,
hasDiscussionsLeft : true ,
hasDiscussionsRight : true ,
} ,
{
left : { } ,
right : { } ,
isMatchLineLeft : true ,
isMatchLineRight : true ,
} ,
{ } ,
{
left : { old _line : 1 , discussions : [ ] } ,
right : { new _line : 1 , discussions : [ ] } ,
} ,
] ;
2021-09-30 23:02:18 +05:30
const createWrapper = ( { props , state = { } , actions , isLoggedIn = true } ) => {
2021-06-08 01:23:25 +05:30
Vue . use ( Vuex ) ;
2021-01-29 00:20:46 +05:30
const diffs = diffsModule ( ) ;
diffs . state = { ... diffs . state , ... state } ;
2021-06-08 01:23:25 +05:30
diffs . actions = { ... diffs . actions , ... actions } ;
2021-01-29 00:20:46 +05:30
const getters = { isLoggedIn : ( ) => isLoggedIn } ;
const store = new Vuex . Store ( {
modules : { diffs } ,
getters ,
} ) ;
2021-09-30 23:02:18 +05:30
window . gon = { current _user _id : isLoggedIn ? 1 : 0 } ;
const coverageFileData = state . coverageFiles ? . files ? state . coverageFiles . files : { } ;
2021-01-29 00:20:46 +05:30
const propsData = {
fileHash : 'abc' ,
filePath : 'abc' ,
line : { } ,
2021-03-08 18:12:59 +05:30
index : 0 ,
2021-09-30 23:02:18 +05:30
isHighlighted : false ,
fileLineCoverage : ( file , line ) => {
const hits = coverageFileData [ file ] ? . [ line ] ;
if ( hits ) {
return { text : ` Test coverage: ${ hits } hits ` , class : 'coverage' } ;
} else if ( hits === 0 ) {
return { text : 'No test coverage' , class : 'no-coverage' } ;
}
return { } ;
} ,
2021-01-29 00:20:46 +05:30
... props ,
} ;
2021-03-08 18:12:59 +05:30
const provide = {
glFeatures : { dragCommentSelection : true } ,
} ;
2021-09-30 23:02:18 +05:30
return shallowMount ( DiffRow , {
propsData ,
store ,
provide ,
listeners : {
enterdragging ,
stopdragging ,
setHighlightedRow ,
showCommentForm ,
} ,
} ) ;
2021-03-08 18:12:59 +05:30
} ;
2021-01-29 00:20:46 +05:30
2021-09-30 23:02:18 +05:30
afterEach ( ( ) => {
wrapper . destroy ( ) ;
wrapper = null ;
2021-01-29 00:20:46 +05:30
2021-09-30 23:02:18 +05:30
window . gon = { } ;
showCommentForm . mockReset ( ) ;
enterdragging . mockReset ( ) ;
stopdragging . mockReset ( ) ;
setHighlightedRow . mockReset ( ) ;
2021-01-29 00:20:46 +05:30
2021-09-30 23:02:18 +05:30
Object . values ( DiffRow ) . forEach ( ( { cache } ) => {
if ( cache ) {
cache . clear ( ) ;
}
} ) ;
2021-01-29 00:20:46 +05:30
} ) ;
2021-09-30 23:02:18 +05:30
const getCommentButton = ( side ) => wrapper . find ( ` [data-testid=" ${ side } -comment-button"] ` ) ;
2021-06-08 01:23:25 +05:30
2021-01-29 00:20:46 +05:30
describe . each `
side
$ { 'left' }
$ { 'right' }
` (' $ side side', ({ side }) => {
it ( ` renders empty cells if ${ side } is unavailable ` , ( ) => {
2021-09-30 23:02:18 +05:30
wrapper = createWrapper ( { props : { line : testLines [ 2 ] , inline : false } } ) ;
2021-06-08 01:23:25 +05:30
expect ( wrapper . find ( ` [data-testid=" ${ side } -line-number"] ` ) . exists ( ) ) . toBe ( false ) ;
expect ( wrapper . find ( ` [data-testid=" ${ side } -empty-cell"] ` ) . exists ( ) ) . toBe ( true ) ;
2021-01-29 00:20:46 +05:30
} ) ;
2021-06-08 01:23:25 +05:30
describe ( 'comment button' , ( ) => {
let line ;
beforeEach ( ( ) => {
// https://eslint.org/docs/rules/prefer-destructuring#when-not-to-use-it
// eslint-disable-next-line prefer-destructuring
line = testLines [ 3 ] ;
} ) ;
it ( 'renders' , ( ) => {
2021-09-30 23:02:18 +05:30
wrapper = createWrapper ( { props : { line , inline : false } } ) ;
expect ( getCommentButton ( side ) . exists ( ) ) . toBe ( true ) ;
2021-06-08 01:23:25 +05:30
} ) ;
it ( 'responds to click and keyboard events' , async ( ) => {
2021-09-30 23:02:18 +05:30
wrapper = createWrapper ( {
2021-06-08 01:23:25 +05:30
props : { line , inline : false } ,
} ) ;
2021-09-30 23:02:18 +05:30
const commentButton = getCommentButton ( side ) ;
2021-06-08 01:23:25 +05:30
await commentButton . trigger ( 'click' ) ;
await commentButton . trigger ( 'keydown.enter' ) ;
await commentButton . trigger ( 'keydown.space' ) ;
expect ( showCommentForm ) . toHaveBeenCalledTimes ( 3 ) ;
} ) ;
it ( 'ignores click and keyboard events when comments are disabled' , async ( ) => {
line [ side ] . commentsDisabled = true ;
2021-09-30 23:02:18 +05:30
wrapper = createWrapper ( {
2021-06-08 01:23:25 +05:30
props : { line , inline : false } ,
} ) ;
2021-09-30 23:02:18 +05:30
const commentButton = getCommentButton ( side ) ;
2021-06-08 01:23:25 +05:30
await commentButton . trigger ( 'click' ) ;
await commentButton . trigger ( 'keydown.enter' ) ;
await commentButton . trigger ( 'keydown.space' ) ;
expect ( showCommentForm ) . not . toHaveBeenCalled ( ) ;
} ) ;
2021-01-29 00:20:46 +05:30
} ) ;
it ( 'renders avatars' , ( ) => {
2021-09-30 23:02:18 +05:30
wrapper = createWrapper ( { props : { line : testLines [ 0 ] , inline : false } } ) ;
2021-06-08 01:23:25 +05:30
expect ( wrapper . find ( ` [data-testid=" ${ side } -discussions"] ` ) . exists ( ) ) . toBe ( true ) ;
2021-01-29 00:20:46 +05:30
} ) ;
} ) ;
it ( 'renders left line numbers' , ( ) => {
2021-09-30 23:02:18 +05:30
wrapper = createWrapper ( { props : { line : testLines [ 0 ] } } ) ;
2021-01-29 00:20:46 +05:30
const lineNumber = testLines [ 0 ] . left . old _line ;
expect ( wrapper . find ( ` [data-linenumber=" ${ lineNumber } "] ` ) . exists ( ) ) . toBe ( true ) ;
} ) ;
it ( 'renders right line numbers' , ( ) => {
2021-09-30 23:02:18 +05:30
wrapper = createWrapper ( { props : { line : testLines [ 0 ] } } ) ;
2021-01-29 00:20:46 +05:30
const lineNumber = testLines [ 0 ] . right . new _line ;
expect ( wrapper . find ( ` [data-linenumber=" ${ lineNumber } "] ` ) . exists ( ) ) . toBe ( true ) ;
} ) ;
2021-03-08 18:12:59 +05:30
describe ( 'drag operations' , ( ) => {
let line ;
beforeEach ( ( ) => {
line = { ... testLines [ 0 ] } ;
} ) ;
it . each `
side
$ { 'left' }
$ { 'right' }
` ('emits ` enterdragging ` onDragEnter $ side side', ({ side }) => {
2021-09-30 23:02:18 +05:30
wrapper = createWrapper ( { props : { line } } ) ;
2021-03-08 18:12:59 +05:30
fireEvent . dragEnter ( getByTestId ( wrapper . element , ` ${ side } -side ` ) ) ;
2021-09-30 23:02:18 +05:30
expect ( enterdragging ) . toHaveBeenCalledWith ( { ... line [ side ] , index : 0 } ) ;
2021-03-08 18:12:59 +05:30
} ) ;
it . each `
side
$ { 'left' }
$ { 'right' }
` ('emits ` stopdragging ` onDrop $ side side', ({ side }) => {
2021-09-30 23:02:18 +05:30
wrapper = createWrapper ( { props : { line } } ) ;
2021-03-08 18:12:59 +05:30
fireEvent . dragEnd ( getByTestId ( wrapper . element , ` ${ side } -side ` ) ) ;
2021-09-30 23:02:18 +05:30
expect ( stopdragging ) . toHaveBeenCalled ( ) ;
2021-03-08 18:12:59 +05:30
} ) ;
} ) ;
describe ( 'sets coverage title and class' , ( ) => {
const thisLine = diffFileMockData . parallel _diff _lines [ 2 ] ;
const rightLine = diffFileMockData . parallel _diff _lines [ 2 ] . right ;
const mockDiffContent = {
diffFile : diffFileMockData ,
shouldRenderDraftRow : jest . fn ( ) ,
hasParallelDraftLeft : jest . fn ( ) ,
hasParallelDraftRight : jest . fn ( ) ,
draftForLine : jest . fn ( ) ,
} ;
const applyMap = mapParallel ( mockDiffContent ) ;
const props = {
line : applyMap ( thisLine ) ,
fileHash : diffFileMockData . file _hash ,
filePath : diffFileMockData . file _path ,
contextLinesPath : 'contextLinesPath' ,
isHighlighted : false ,
} ;
const name = diffFileMockData . file _path ;
const line = rightLine . new _line ;
it ( 'for lines with coverage' , ( ) => {
const coverageFiles = { files : { [ name ] : { [ line ] : 5 } } } ;
2021-09-30 23:02:18 +05:30
wrapper = createWrapper ( { props , state : { coverageFiles } } ) ;
2021-03-08 18:12:59 +05:30
const coverage = wrapper . find ( '.line-coverage.right-side' ) ;
expect ( coverage . attributes ( 'title' ) ) . toContain ( 'Test coverage: 5 hits' ) ;
expect ( coverage . classes ( 'coverage' ) ) . toBeTruthy ( ) ;
} ) ;
it ( 'for lines without coverage' , ( ) => {
const coverageFiles = { files : { [ name ] : { [ line ] : 0 } } } ;
2021-09-30 23:02:18 +05:30
wrapper = createWrapper ( { props , state : { coverageFiles } } ) ;
2021-03-08 18:12:59 +05:30
const coverage = wrapper . find ( '.line-coverage.right-side' ) ;
expect ( coverage . attributes ( 'title' ) ) . toContain ( 'No test coverage' ) ;
expect ( coverage . classes ( 'no-coverage' ) ) . toBeTruthy ( ) ;
} ) ;
it ( 'for unknown lines' , ( ) => {
const coverageFiles = { } ;
2021-09-30 23:02:18 +05:30
wrapper = createWrapper ( { props , state : { coverageFiles } } ) ;
2021-03-08 18:12:59 +05:30
const coverage = wrapper . find ( '.line-coverage.right-side' ) ;
expect ( coverage . attributes ( 'title' ) ) . toBeFalsy ( ) ;
expect ( coverage . classes ( 'coverage' ) ) . toBeFalsy ( ) ;
expect ( coverage . classes ( 'no-coverage' ) ) . toBeFalsy ( ) ;
} ) ;
} ) ;
2021-04-29 21:17:54 +05:30
describe ( 'interoperability' , ( ) => {
it . each `
desc | line | inline | leftSide | rightSide
$ { 'with inline and new_line' } | $ { { left : { old _line : 3 , new _line : 5 , type : 'new' } } } | $ { true } | $ { { type : 'new' , line : '5' , oldLine : '3' , newLine : '5' } } | $ { null }
$ { 'with inline and no new_line' } | $ { { left : { old _line : 3 , type : 'old' } } } | $ { true } | $ { { type : 'old' , line : '3' , oldLine : '3' } } | $ { null }
$ { 'with parallel and no right side' } | $ { { left : { old _line : 3 , new _line : 5 } } } | $ { false } | $ { { type : 'old' , line : '3' , oldLine : '3' } } | $ { null }
$ { 'with parallel and no left side' } | $ { { right : { old _line : 3 , new _line : 5 } } } | $ { false } | $ { null } | $ { { type : 'new' , line : '5' , newLine : '5' } }
$ { 'with parallel and right side' } | $ { { left : { old _line : 3 } , right : { new _line : 5 } } } | $ { false } | $ { { type : 'old' , line : '3' , oldLine : '3' } } | $ { { type : 'new' , line : '5' , newLine : '5' } }
` (' $ desc, sets interop data attributes', ({ line, inline, leftSide, rightSide }) => {
2021-09-30 23:02:18 +05:30
wrapper = createWrapper ( { props : { line , inline } } ) ;
2021-04-29 21:17:54 +05:30
expect ( findInteropAttributes ( wrapper , '[data-testid="left-side"]' ) ) . toEqual ( leftSide ) ;
expect ( findInteropAttributes ( wrapper , '[data-testid="right-side"]' ) ) . toEqual ( rightSide ) ;
} ) ;
} ) ;
2021-01-29 00:20:46 +05:30
} ) ;