Commit 27bdfb89 authored by Miguel Rincon's avatar Miguel Rincon

Merge branch 'jdb/highlight-commented-rows' into 'master'

Highlight commented rows

See merge request gitlab-org/gitlab!34432
parents 7ff33777 cfdf5b19
...@@ -51,6 +51,7 @@ export default { ...@@ -51,6 +51,7 @@ export default {
'scrollToDraft', 'scrollToDraft',
'toggleResolveDiscussion', 'toggleResolveDiscussion',
]), ]),
...mapActions(['setSelectedCommentPositionHover']),
update(data) { update(data) {
this.updateDraft(data); this.updateDraft(data);
}, },
...@@ -67,7 +68,11 @@ export default { ...@@ -67,7 +68,11 @@ export default {
}; };
</script> </script>
<template> <template>
<article class="draft-note-component note-wrapper"> <article
class="draft-note-component note-wrapper"
@mouseenter="setSelectedCommentPositionHover(draft.position.line_range)"
@mouseleave="setSelectedCommentPositionHover()"
>
<ul class="notes draft-notes"> <ul class="notes draft-notes">
<noteable-note <noteable-note
:note="draft" :note="draft"
......
...@@ -148,10 +148,7 @@ export default { ...@@ -148,10 +148,7 @@ export default {
<template> <template>
<div class="content discussion-form discussion-form-container discussion-notes"> <div class="content discussion-form discussion-form-container discussion-notes">
<div <div v-if="glFeatures.multilineComments" class="gl-mb-3 gl-text-gray-700 gl-pb-3">
v-if="glFeatures.multilineComments"
class="gl-mb-3 gl-text-gray-700 gl-border-gray-100 gl-border-b-solid gl-border-b-1 gl-pb-3"
>
<multiline-comment-form <multiline-comment-form
v-model="commentLineStart" v-model="commentLineStart"
:line="line" :line="line"
......
...@@ -37,6 +37,11 @@ export default { ...@@ -37,6 +37,11 @@ export default {
required: false, required: false,
default: false, default: false,
}, },
isCommented: {
type: Boolean,
required: false,
default: false,
},
}, },
data() { data() {
return { return {
...@@ -47,7 +52,10 @@ export default { ...@@ -47,7 +52,10 @@ export default {
...mapGetters('diffs', ['fileLineCoverage']), ...mapGetters('diffs', ['fileLineCoverage']),
...mapState({ ...mapState({
isHighlighted(state) { isHighlighted(state) {
return this.line.line_code !== null && this.line.line_code === state.diffs.highlightedRow; if (this.isCommented) return true;
const lineCode = this.line.line_code;
return lineCode ? lineCode === state.diffs.highlightedRow : false;
}, },
}), }),
isContextLine() { isContextLine() {
......
<script> <script>
import { mapGetters } from 'vuex'; import { mapGetters, mapState } from 'vuex';
import draftCommentsMixin from '~/diffs/mixins/draft_comments'; import draftCommentsMixin from '~/diffs/mixins/draft_comments';
import InlineDraftCommentRow from '~/batch_comments/components/inline_draft_comment_row.vue'; import InlineDraftCommentRow from '~/batch_comments/components/inline_draft_comment_row.vue';
import inlineDiffTableRow from './inline_diff_table_row.vue'; import inlineDiffTableRow from './inline_diff_table_row.vue';
import inlineDiffCommentRow from './inline_diff_comment_row.vue'; import inlineDiffCommentRow from './inline_diff_comment_row.vue';
import inlineDiffExpansionRow from './inline_diff_expansion_row.vue'; import inlineDiffExpansionRow from './inline_diff_expansion_row.vue';
import { getCommentedLines } from '~/notes/components/multiline_comment_utils';
export default { export default {
components: { components: {
...@@ -31,9 +32,19 @@ export default { ...@@ -31,9 +32,19 @@ export default {
}, },
computed: { computed: {
...mapGetters('diffs', ['commitId']), ...mapGetters('diffs', ['commitId']),
...mapState({
selectedCommentPosition: ({ notes }) => notes.selectedCommentPosition,
selectedCommentPositionHover: ({ notes }) => notes.selectedCommentPositionHover,
}),
diffLinesLength() { diffLinesLength() {
return this.diffLines.length; return this.diffLines.length;
}, },
commentedLines() {
return getCommentedLines(
this.selectedCommentPosition || this.selectedCommentPositionHover,
this.diffLines,
);
},
}, },
userColorScheme: window.gon.user_color_scheme, userColorScheme: window.gon.user_color_scheme,
}; };
...@@ -67,6 +78,7 @@ export default { ...@@ -67,6 +78,7 @@ export default {
:file-path="diffFile.file_path" :file-path="diffFile.file_path"
:line="line" :line="line"
:is-bottom="index + 1 === diffLinesLength" :is-bottom="index + 1 === diffLinesLength"
:is-commented="index >= commentedLines.startLine && index <= commentedLines.endLine"
/> />
<inline-diff-comment-row <inline-diff-comment-row
:key="`icr-${line.line_code || index}`" :key="`icr-${line.line_code || index}`"
......
...@@ -40,6 +40,11 @@ export default { ...@@ -40,6 +40,11 @@ export default {
required: false, required: false,
default: false, default: false,
}, },
isCommented: {
type: Boolean,
required: false,
default: false,
},
}, },
data() { data() {
return { return {
...@@ -51,6 +56,8 @@ export default { ...@@ -51,6 +56,8 @@ export default {
...mapGetters('diffs', ['fileLineCoverage']), ...mapGetters('diffs', ['fileLineCoverage']),
...mapState({ ...mapState({
isHighlighted(state) { isHighlighted(state) {
if (this.isCommented) return true;
const lineCode = const lineCode =
(this.line.left && this.line.left.line_code) || (this.line.left && this.line.left.line_code) ||
(this.line.right && this.line.right.line_code); (this.line.right && this.line.right.line_code);
......
<script> <script>
import { mapGetters } from 'vuex'; import { mapGetters, mapState } from 'vuex';
import draftCommentsMixin from '~/diffs/mixins/draft_comments'; import draftCommentsMixin from '~/diffs/mixins/draft_comments';
import ParallelDraftCommentRow from '~/batch_comments/components/parallel_draft_comment_row.vue'; import ParallelDraftCommentRow from '~/batch_comments/components/parallel_draft_comment_row.vue';
import parallelDiffTableRow from './parallel_diff_table_row.vue'; import parallelDiffTableRow from './parallel_diff_table_row.vue';
import parallelDiffCommentRow from './parallel_diff_comment_row.vue'; import parallelDiffCommentRow from './parallel_diff_comment_row.vue';
import parallelDiffExpansionRow from './parallel_diff_expansion_row.vue'; import parallelDiffExpansionRow from './parallel_diff_expansion_row.vue';
import { getCommentedLines } from '~/notes/components/multiline_comment_utils';
export default { export default {
components: { components: {
...@@ -31,9 +32,19 @@ export default { ...@@ -31,9 +32,19 @@ export default {
}, },
computed: { computed: {
...mapGetters('diffs', ['commitId']), ...mapGetters('diffs', ['commitId']),
...mapState({
selectedCommentPosition: ({ notes }) => notes.selectedCommentPosition,
selectedCommentPositionHover: ({ notes }) => notes.selectedCommentPositionHover,
}),
diffLinesLength() { diffLinesLength() {
return this.diffLines.length; return this.diffLines.length;
}, },
commentedLines() {
return getCommentedLines(
this.selectedCommentPosition || this.selectedCommentPositionHover,
this.diffLines,
);
},
}, },
userColorScheme: window.gon.user_color_scheme, userColorScheme: window.gon.user_color_scheme,
}; };
...@@ -69,6 +80,7 @@ export default { ...@@ -69,6 +80,7 @@ export default {
:file-path="diffFile.file_path" :file-path="diffFile.file_path"
:line="line" :line="line"
:is-bottom="index + 1 === diffLinesLength" :is-bottom="index + 1 === diffLinesLength"
:is-commented="index >= commentedLines.startLine && index <= commentedLines.endLine"
/> />
<parallel-diff-comment-row <parallel-diff-comment-row
:key="`dcr-${line.line_code || index}`" :key="`dcr-${line.line_code || index}`"
......
...@@ -74,7 +74,7 @@ export default { ...@@ -74,7 +74,7 @@ export default {
}, },
}, },
methods: { methods: {
...mapActions(['toggleDiscussion']), ...mapActions(['toggleDiscussion', 'setSelectedCommentPositionHover']),
componentName(note) { componentName(note) {
if (note.isPlaceholderNote) { if (note.isPlaceholderNote) {
if (note.placeholderType === SYSTEM_NOTE) { if (note.placeholderType === SYSTEM_NOTE) {
...@@ -99,7 +99,11 @@ export default { ...@@ -99,7 +99,11 @@ export default {
<template> <template>
<div class="discussion-notes"> <div class="discussion-notes">
<ul class="notes"> <ul
class="notes"
@mouseenter="setSelectedCommentPositionHover(discussion.position.line_range)"
@mouseleave="setSelectedCommentPositionHover()"
>
<template v-if="shouldGroupReplies"> <template v-if="shouldGroupReplies">
<component <component
:is="componentName(firstNote)" :is="componentName(firstNote)"
......
<script> <script>
import { mapActions } from 'vuex';
import { GlFormSelect, GlSprintf } from '@gitlab/ui'; import { GlFormSelect, GlSprintf } from '@gitlab/ui';
import { getSymbol, getLineClasses } from './multiline_comment_utils'; import { getSymbol, getLineClasses } from './multiline_comment_utils';
...@@ -39,8 +40,13 @@ export default { ...@@ -39,8 +40,13 @@ export default {
old_line: line.old_line, old_line: line.old_line,
new_line: line.new_line, new_line: line.new_line,
}; };
this.highlightSelection();
},
destroyed() {
this.setSelectedCommentPosition();
}, },
methods: { methods: {
...mapActions(['setSelectedCommentPosition']),
getSymbol({ type }) { getSymbol({ type }) {
return getSymbol(type); return getSymbol(type);
}, },
...@@ -50,6 +56,16 @@ export default { ...@@ -50,6 +56,16 @@ export default {
updateCommentLineStart(value) { updateCommentLineStart(value) {
this.commentLineStart = value; this.commentLineStart = value;
this.$emit('input', value); this.$emit('input', value);
this.highlightSelection();
},
highlightSelection() {
const { line_code, new_line, old_line, type } = this.line;
const updatedLineRange = {
start: { ...this.commentLineStart },
end: { line_code, new_line, old_line, type },
};
this.setSelectedCommentPosition(updatedLineRange);
}, },
}, },
}; };
......
...@@ -90,3 +90,22 @@ export function formatLineRange(start, end) { ...@@ -90,3 +90,22 @@ export function formatLineRange(start, end) {
end: extractProps(end), end: extractProps(end),
}; };
} }
export function getCommentedLines(selectedCommentPosition, diffLines) {
if (!selectedCommentPosition) {
// This structure simplifies the logic that consumes this result
// by keeping the returned shape the same and adjusting the bounds
// to something unreachable. This way our component logic stays:
// "if index between start and end"
return {
startLine: diffLines.length + 1,
endLine: diffLines.length + 1,
};
}
const { start, end } = selectedCommentPosition;
const startLine = diffLines.findIndex(l => l.line_code === start.line_code);
const endLine = diffLines.findIndex(l => l.line_code === end.line_code);
return { startLine, endLine };
}
...@@ -186,6 +186,7 @@ export default { ...@@ -186,6 +186,7 @@ export default {
eventHub.$on('enterEditMode', ({ noteId }) => { eventHub.$on('enterEditMode', ({ noteId }) => {
if (noteId === this.note.id) { if (noteId === this.note.id) {
this.isEditing = true; this.isEditing = true;
this.setSelectedCommentPositionHover();
this.scrollToNoteIfNeeded($(this.$el)); this.scrollToNoteIfNeeded($(this.$el));
} }
}); });
...@@ -205,9 +206,11 @@ export default { ...@@ -205,9 +206,11 @@ export default {
'toggleResolveNote', 'toggleResolveNote',
'scrollToNoteIfNeeded', 'scrollToNoteIfNeeded',
'updateAssignees', 'updateAssignees',
'setSelectedCommentPositionHover',
]), ]),
editHandler() { editHandler() {
this.isEditing = true; this.isEditing = true;
this.setSelectedCommentPositionHover();
this.$emit('handleEdit'); this.$emit('handleEdit');
}, },
deleteHandler() { deleteHandler() {
...@@ -284,6 +287,7 @@ export default { ...@@ -284,6 +287,7 @@ export default {
} else { } else {
this.isRequesting = false; this.isRequesting = false;
this.isEditing = true; this.isEditing = true;
this.setSelectedCommentPositionHover();
this.$nextTick(() => { this.$nextTick(() => {
const msg = __('Something went wrong while editing your comment. Please try again.'); const msg = __('Something went wrong while editing your comment. Please try again.');
Flash(msg, 'alert', this.$el); Flash(msg, 'alert', this.$el);
...@@ -340,7 +344,7 @@ export default { ...@@ -340,7 +344,7 @@ export default {
:line="line" :line="line"
:comment-line-options="commentLineOptions" :comment-line-options="commentLineOptions"
:line-range="note.position.line_range" :line-range="note.position.line_range"
class="gl-mb-3 gl-text-gray-700 gl-border-gray-100 gl-border-b-solid gl-border-b-1 gl-pb-3" class="gl-mb-3 gl-text-gray-700 gl-pb-3"
/> />
<div <div
v-else v-else
......
...@@ -99,6 +99,14 @@ export const setDiscussionSortDirection = ({ commit }, direction) => { ...@@ -99,6 +99,14 @@ export const setDiscussionSortDirection = ({ commit }, direction) => {
commit(types.SET_DISCUSSIONS_SORT, direction); commit(types.SET_DISCUSSIONS_SORT, direction);
}; };
export const setSelectedCommentPosition = ({ commit }, position) => {
commit(types.SET_SELECTED_COMMENT_POSITION, position);
};
export const setSelectedCommentPositionHover = ({ commit }, position) => {
commit(types.SET_SELECTED_COMMENT_POSITION_HOVER, position);
};
export const removeNote = ({ commit, dispatch, state }, note) => { export const removeNote = ({ commit, dispatch, state }, note) => {
const discussion = state.discussions.find(({ id }) => id === note.discussion_id); const discussion = state.discussions.find(({ id }) => id === note.discussion_id);
......
...@@ -12,6 +12,15 @@ export default () => ({ ...@@ -12,6 +12,15 @@ export default () => ({
lastFetchedAt: null, lastFetchedAt: null,
currentDiscussionId: null, currentDiscussionId: null,
batchSuggestionsInfo: [], batchSuggestionsInfo: [],
/**
* selectedCommentPosition & selectedCommentPosition structures are the same as `position.line_range`:
* {
* start: { line_code: string, new_line: number, old_line:number, type: string },
* end: { line_code: string, new_line: number, old_line:number, type: string },
* }
*/
selectedCommentPosition: null,
selectedCommentPositionHover: null,
// View layer // View layer
isToggleStateButtonLoading: false, isToggleStateButtonLoading: false,
......
...@@ -33,6 +33,8 @@ export const SET_EXPAND_DISCUSSIONS = 'SET_EXPAND_DISCUSSIONS'; ...@@ -33,6 +33,8 @@ export const SET_EXPAND_DISCUSSIONS = 'SET_EXPAND_DISCUSSIONS';
export const UPDATE_RESOLVABLE_DISCUSSIONS_COUNTS = 'UPDATE_RESOLVABLE_DISCUSSIONS_COUNTS'; export const UPDATE_RESOLVABLE_DISCUSSIONS_COUNTS = 'UPDATE_RESOLVABLE_DISCUSSIONS_COUNTS';
export const SET_CURRENT_DISCUSSION_ID = 'SET_CURRENT_DISCUSSION_ID'; export const SET_CURRENT_DISCUSSION_ID = 'SET_CURRENT_DISCUSSION_ID';
export const SET_DISCUSSIONS_SORT = 'SET_DISCUSSIONS_SORT'; export const SET_DISCUSSIONS_SORT = 'SET_DISCUSSIONS_SORT';
export const SET_SELECTED_COMMENT_POSITION = 'SET_SELECTED_COMMENT_POSITION';
export const SET_SELECTED_COMMENT_POSITION_HOVER = 'SET_SELECTED_COMMENT_POSITION_HOVER';
// Issue // Issue
export const CLOSE_ISSUE = 'CLOSE_ISSUE'; export const CLOSE_ISSUE = 'CLOSE_ISSUE';
......
...@@ -308,6 +308,14 @@ export default { ...@@ -308,6 +308,14 @@ export default {
state.discussionSortOrder = sort; state.discussionSortOrder = sort;
}, },
[types.SET_SELECTED_COMMENT_POSITION](state, position) {
state.selectedCommentPosition = position;
},
[types.SET_SELECTED_COMMENT_POSITION_HOVER](state, position) {
state.selectedCommentPositionHover = position;
},
[types.DISABLE_COMMENTS](state, value) { [types.DISABLE_COMMENTS](state, value) {
state.commentsDisabled = value; state.commentsDisabled = value;
}, },
......
---
title: Highlight commented rows
merge_request: 34432
author:
type: added
import Vue from 'vue'; import { shallowMount } from '@vue/test-utils';
import { createComponentWithStore } from 'helpers/vue_mount_component_helper';
import { createStore } from '~/mr_notes/stores'; import { createStore } from '~/mr_notes/stores';
import InlineDiffTableRow from '~/diffs/components/inline_diff_table_row.vue'; import InlineDiffTableRow from '~/diffs/components/inline_diff_table_row.vue';
import diffFileMockData from '../mock_data/diff_file'; import diffFileMockData from '../mock_data/diff_file';
describe('InlineDiffTableRow', () => { describe('InlineDiffTableRow', () => {
let wrapper;
let vm; let vm;
const thisLine = diffFileMockData.highlighted_diff_lines[0]; const thisLine = diffFileMockData.highlighted_diff_lines[0];
beforeEach(() => { beforeEach(() => {
vm = createComponentWithStore(Vue.extend(InlineDiffTableRow), createStore(), { wrapper = shallowMount(InlineDiffTableRow, {
line: thisLine, store: createStore(),
fileHash: diffFileMockData.file_hash, propsData: {
filePath: diffFileMockData.file_path, line: thisLine,
contextLinesPath: 'contextLinesPath', fileHash: diffFileMockData.file_hash,
isHighlighted: false, filePath: diffFileMockData.file_path,
}).$mount(); contextLinesPath: 'contextLinesPath',
isHighlighted: false,
},
});
vm = wrapper.vm;
}); });
it('does not add hll class to line content when line does not match highlighted row', done => { it('does not add hll class to line content when line does not match highlighted row', done => {
vm.$nextTick() vm.$nextTick()
.then(() => { .then(() => {
expect(vm.$el.querySelector('.line_content').classList).not.toContain('hll'); expect(wrapper.find('.line_content').classes('hll')).toBe(false);
}) })
.then(done) .then(done)
.catch(done.fail); .catch(done.fail);
...@@ -35,12 +39,19 @@ describe('InlineDiffTableRow', () => { ...@@ -35,12 +39,19 @@ describe('InlineDiffTableRow', () => {
return vm.$nextTick(); return vm.$nextTick();
}) })
.then(() => { .then(() => {
expect(vm.$el.querySelector('.line_content').classList).toContain('hll'); expect(wrapper.find('.line_content').classes('hll')).toBe(true);
}) })
.then(done) .then(done)
.catch(done.fail); .catch(done.fail);
}); });
it('adds hll class to lineContent when line is part of a multiline comment', () => {
wrapper.setProps({ isCommented: true });
return vm.$nextTick().then(() => {
expect(wrapper.find('.line_content').classes('hll')).toBe(true);
});
});
describe('sets coverage title and class', () => { describe('sets coverage title and class', () => {
it('for lines with coverage', done => { it('for lines with coverage', done => {
vm.$nextTick() vm.$nextTick()
...@@ -53,10 +64,10 @@ describe('InlineDiffTableRow', () => { ...@@ -53,10 +64,10 @@ describe('InlineDiffTableRow', () => {
return vm.$nextTick(); return vm.$nextTick();
}) })
.then(() => { .then(() => {
const coverage = vm.$el.querySelector('.line-coverage'); const coverage = wrapper.find('.line-coverage');
expect(coverage.title).toContain('Test coverage: 5 hits'); expect(coverage.attributes('title')).toContain('Test coverage: 5 hits');
expect(coverage.classList).toContain('coverage'); expect(coverage.classes('coverage')).toBe(true);
}) })
.then(done) .then(done)
.catch(done.fail); .catch(done.fail);
...@@ -73,10 +84,10 @@ describe('InlineDiffTableRow', () => { ...@@ -73,10 +84,10 @@ describe('InlineDiffTableRow', () => {
return vm.$nextTick(); return vm.$nextTick();
}) })
.then(() => { .then(() => {
const coverage = vm.$el.querySelector('.line-coverage'); const coverage = wrapper.find('.line-coverage');
expect(coverage.title).toContain('No test coverage'); expect(coverage.attributes('title')).toContain('No test coverage');
expect(coverage.classList).toContain('no-coverage'); expect(coverage.classes('no-coverage')).toBe(true);
}) })
.then(done) .then(done)
.catch(done.fail); .catch(done.fail);
...@@ -90,11 +101,11 @@ describe('InlineDiffTableRow', () => { ...@@ -90,11 +101,11 @@ describe('InlineDiffTableRow', () => {
return vm.$nextTick(); return vm.$nextTick();
}) })
.then(() => { .then(() => {
const coverage = vm.$el.querySelector('.line-coverage'); const coverage = wrapper.find('.line-coverage');
expect(coverage.title).not.toContain('Coverage'); expect(coverage.attributes('title')).toBeUndefined();
expect(coverage.classList).not.toContain('coverage'); expect(coverage.classes('coverage')).toBe(false);
expect(coverage.classList).not.toContain('no-coverage'); expect(coverage.classes('no-coverage')).toBe(false);
}) })
.then(done) .then(done)
.catch(done.fail); .catch(done.fail);
......
import Vue from 'vue'; import Vue from 'vue';
import { shallowMount } from '@vue/test-utils';
import { createComponentWithStore } from 'helpers/vue_mount_component_helper'; import { createComponentWithStore } from 'helpers/vue_mount_component_helper';
import { createStore } from '~/mr_notes/stores'; import { createStore } from '~/mr_notes/stores';
import ParallelDiffTableRow from '~/diffs/components/parallel_diff_table_row.vue'; import ParallelDiffTableRow from '~/diffs/components/parallel_diff_table_row.vue';
...@@ -6,18 +7,24 @@ import diffFileMockData from '../mock_data/diff_file'; ...@@ -6,18 +7,24 @@ import diffFileMockData from '../mock_data/diff_file';
describe('ParallelDiffTableRow', () => { describe('ParallelDiffTableRow', () => {
describe('when one side is empty', () => { describe('when one side is empty', () => {
let wrapper;
let vm; let vm;
const thisLine = diffFileMockData.parallel_diff_lines[0]; const thisLine = diffFileMockData.parallel_diff_lines[0];
const rightLine = diffFileMockData.parallel_diff_lines[0].right; const rightLine = diffFileMockData.parallel_diff_lines[0].right;
beforeEach(() => { beforeEach(() => {
vm = createComponentWithStore(Vue.extend(ParallelDiffTableRow), createStore(), { wrapper = shallowMount(ParallelDiffTableRow, {
line: thisLine, store: createStore(),
fileHash: diffFileMockData.file_hash, propsData: {
filePath: diffFileMockData.file_path, line: thisLine,
contextLinesPath: 'contextLinesPath', fileHash: diffFileMockData.file_hash,
isHighlighted: false, filePath: diffFileMockData.file_path,
}).$mount(); contextLinesPath: 'contextLinesPath',
isHighlighted: false,
},
});
vm = wrapper.vm;
}); });
it('does not highlight non empty line content when line does not match highlighted row', done => { it('does not highlight non empty line content when line does not match highlighted row', done => {
...@@ -42,6 +49,13 @@ describe('ParallelDiffTableRow', () => { ...@@ -42,6 +49,13 @@ describe('ParallelDiffTableRow', () => {
.then(done) .then(done)
.catch(done.fail); .catch(done.fail);
}); });
it('highlights nonempty line content when line is part of a multiline comment', () => {
wrapper.setProps({ isCommented: true });
return vm.$nextTick().then(() => {
expect(vm.$el.querySelector('.line_content.right-side').classList).toContain('hll');
});
});
}); });
describe('when both sides have content', () => { describe('when both sides have content', () => {
......
...@@ -2,6 +2,7 @@ import { ...@@ -2,6 +2,7 @@ import {
getSymbol, getSymbol,
getStartLineNumber, getStartLineNumber,
getEndLineNumber, getEndLineNumber,
getCommentedLines,
} from '~/notes/components/multiline_comment_utils'; } from '~/notes/components/multiline_comment_utils';
describe('Multiline comment utilities', () => { describe('Multiline comment utilities', () => {
...@@ -33,4 +34,30 @@ describe('Multiline comment utilities', () => { ...@@ -33,4 +34,30 @@ describe('Multiline comment utilities', () => {
expect(getSymbol(type)).toEqual(result); expect(getSymbol(type)).toEqual(result);
}); });
}); });
describe('getCommentedLines', () => {
const diffLines = [{ line_code: '1' }, { line_code: '2' }, { line_code: '3' }];
it('returns a default object when `selectedCommentPosition` is not provided', () => {
expect(getCommentedLines(undefined, diffLines)).toEqual({ startLine: 4, endLine: 4 });
});
it('returns an object with startLine and endLine equal to 0', () => {
const selectedCommentPosition = {
start: { line_code: '1' },
end: { line_code: '1' },
};
expect(getCommentedLines(selectedCommentPosition, diffLines)).toEqual({
startLine: 0,
endLine: 0,
});
});
it('returns an object with startLine and endLine equal to 0 and 1', () => {
const selectedCommentPosition = {
start: { line_code: '1' },
end: { line_code: '2' },
};
expect(getCommentedLines(selectedCommentPosition, diffLines)).toEqual({
startLine: 0,
endLine: 1,
});
});
});
}); });
...@@ -175,6 +175,7 @@ describe('issue_note', () => { ...@@ -175,6 +175,7 @@ describe('issue_note', () => {
store.hotUpdate({ store.hotUpdate({
actions: { actions: {
updateNote() {}, updateNote() {},
setSelectedCommentPositionHover() {},
}, },
}); });
const noteBodyComponent = wrapper.find(NoteBody); const noteBodyComponent = wrapper.find(NoteBody);
......
...@@ -1127,6 +1127,19 @@ describe('Actions Notes Store', () => { ...@@ -1127,6 +1127,19 @@ describe('Actions Notes Store', () => {
}); });
}); });
describe('setSelectedCommentPosition', () => {
it('calls the correct mutation with the correct args', done => {
testAction(
actions.setSelectedCommentPosition,
{},
{},
[{ type: mutationTypes.SET_SELECTED_COMMENT_POSITION, payload: {} }],
[],
done,
);
});
});
describe('softDeleteDescriptionVersion', () => { describe('softDeleteDescriptionVersion', () => {
const endpoint = '/path/to/diff/1'; const endpoint = '/path/to/diff/1';
const payload = { const payload = {
......
...@@ -524,6 +524,26 @@ describe('Notes Store mutations', () => { ...@@ -524,6 +524,26 @@ describe('Notes Store mutations', () => {
}); });
}); });
describe('SET_SELECTED_COMMENT_POSITION', () => {
it('should set comment position state', () => {
const state = {};
mutations.SET_SELECTED_COMMENT_POSITION(state, {});
expect(state.selectedCommentPosition).toEqual({});
});
});
describe('SET_SELECTED_COMMENT_POSITION_HOVER', () => {
it('should set comment hover position state', () => {
const state = {};
mutations.SET_SELECTED_COMMENT_POSITION_HOVER(state, {});
expect(state.selectedCommentPositionHover).toEqual({});
});
});
describe('DISABLE_COMMENTS', () => { describe('DISABLE_COMMENTS', () => {
it('should set comments disabled state', () => { it('should set comments disabled state', () => {
const state = {}; const state = {};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment