Commit cfdf5b19 authored by Justin Boyson's avatar Justin Boyson Committed by Miguel Rincon

Fix saving state between hover and start change

Save two separate states for hover and start selection.
Make start selection be the default.
parent e118d7ba
...@@ -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