diff --git a/app/assets/javascripts/notes/components/discussion_notes.vue b/app/assets/javascripts/notes/components/discussion_notes.vue index 78953a627330113c7055c3e88042618d5365002c..f626d689b3d7cb0238b246a41ba299bb3d9cc01e 100644 --- a/app/assets/javascripts/notes/components/discussion_notes.vue +++ b/app/assets/javascripts/notes/components/discussion_notes.vue @@ -137,6 +137,7 @@ export default { :is="componentName(firstNote)" :note="componentData(firstNote)" :line="line || diffLine" + :discussion="discussion" :discussion-file="discussion.diff_file" :commit="commit" :help-page-path="helpPagePath" diff --git a/app/assets/javascripts/notes/components/note_body.vue b/app/assets/javascripts/notes/components/note_body.vue index 1bf4fec6cebb87c3ff07e5f8a58ac3fc4888603e..100bd2fcc206853c2d2d8602d2e5e36fc2fd86b3 100644 --- a/app/assets/javascripts/notes/components/note_body.vue +++ b/app/assets/javascripts/notes/components/note_body.vue @@ -36,6 +36,11 @@ export default { required: false, default: null, }, + lines: { + type: Array, + required: false, + default: () => [], + }, file: { type: Object, required: false, @@ -234,6 +239,7 @@ export default { :note-body="noteBody" :note-id="note.id" :line="line" + :lines="lines" :note="note" :diff-file="file" :save-button-title="saveButtonTitle" diff --git a/app/assets/javascripts/notes/components/noteable_note.vue b/app/assets/javascripts/notes/components/noteable_note.vue index 367e3fbc743b4076ef5f686cddc0302168a3ef4e..da7ff174b6703523a733e9ffd8cd657ddfb45bf2 100644 --- a/app/assets/javascripts/notes/components/noteable_note.vue +++ b/app/assets/javascripts/notes/components/noteable_note.vue @@ -182,6 +182,9 @@ export default { } return ''; }, + commentLines() { + return this.getLinesForDiscussion({ discussion: this.discussion }); + }, actionText() { if (!this.commit) { return ''; @@ -281,6 +284,7 @@ export default { 'updateAssignees', 'setSelectedCommentPositionHover', ]), + ...mapActions(useLegacyDiffs, ['getLinesForDiscussion']), editHandler() { this.isEditing = true; this.setSelectedCommentPositionHover(); @@ -539,6 +543,7 @@ export default { :note="note" :can-edit="canEdit" :line="line" + :lines="commentLines" :file="diffFile" :is-editing="isEditing" :autosave-key="autosaveKey" diff --git a/spec/frontend/notes/components/note_body_spec.js b/spec/frontend/notes/components/note_body_spec.js index 9be25fc4a87e82926f7934d45406ea8859948ca1..b6f90b3a5e0bd4eebc722458216bd5fe655dcd7d 100644 --- a/spec/frontend/notes/components/note_body_spec.js +++ b/spec/frontend/notes/components/note_body_spec.js @@ -87,6 +87,23 @@ describe('issue_note_body component', () => { expect(wrapper.findComponent(NoteForm).props('saveButtonTitle')).toBe(buttonText); }); + it.each` + type | value + ${'simple'} | ${[]} + ${'complex'} | ${[{ line_code: 'a' }, { line_code: 'b' }]} + `('provides the correct lines to the note form ($type)', ({ value }) => { + createComponent({ + isEditing: true, + autosaveKey, + restoreFromAutosave: true, + lines: value, + }); + + const form = wrapper.findComponent(NoteForm); + + expect(form.props('lines')).toEqual(value); + }); + describe('isInternalNote', () => { beforeEach(() => { wrapper.setProps({ isInternalNote: true }); diff --git a/spec/frontend/notes/components/noteable_note_spec.js b/spec/frontend/notes/components/noteable_note_spec.js index 65c234bcddc4423562755e63b47ac77b91c2af9f..9ec74adfe37cb6e88c458f3bc8e4db6de6e95adf 100644 --- a/spec/frontend/notes/components/noteable_note_spec.js +++ b/spec/frontend/notes/components/noteable_note_spec.js @@ -5,6 +5,7 @@ import { createTestingPinia } from '@pinia/testing'; import { PiniaVuePlugin } from 'pinia'; import { mountExtended } from 'helpers/vue_test_utils_helper'; import waitForPromises from 'helpers/wait_for_promises'; +import { getDiffFileMock } from 'jest/diffs/mock_data/diff_file'; import NoteActions from '~/notes/components/note_actions.vue'; import NoteBody from '~/notes/components/note_body.vue'; import NoteHeader from '~/notes/components/note_header.vue'; @@ -20,7 +21,7 @@ import { useMockInternalEventsTracking } from 'helpers/tracking_internal_events_ import { globalAccessorPlugin } from '~/pinia/plugins'; import { useLegacyDiffs } from '~/diffs/stores/legacy_diffs'; import { useNotes } from '~/notes/store/legacy_notes'; -import { noteableDataMock, notesDataMock, note } from '../mock_data'; +import { noteableDataMock, notesDataMock, discussionMock, note } from '../mock_data'; Vue.use(PiniaVuePlugin); @@ -48,6 +49,7 @@ const singleLineNotePosition = { describe('issue_note', () => { let pinia; + let diffsStore; let wrapper; const REPORT_ABUSE_PATH = '/abuse_reports/add_category'; @@ -79,12 +81,16 @@ describe('issue_note', () => { }); }; - beforeEach(() => { - pinia = createTestingPinia({ plugins: [globalAccessorPlugin] }); - useLegacyDiffs(); + const createPinia = ({ stubActions = true } = {}) => { + pinia = createTestingPinia({ stubActions, plugins: [globalAccessorPlugin] }); + diffsStore = useLegacyDiffs(); useNotes().noteableData = noteableDataMock; useNotes().notesData = notesDataMock; useNotes().updateNote.mockResolvedValue(); + }; + + beforeEach(() => { + createPinia(); }); describe('mutiline comments', () => { @@ -194,6 +200,48 @@ describe('issue_note', () => { it('should not render if `line_range` is unavailable', () => { expect(findMultilineComment().exists()).toBe(false); }); + + describe('multi-line line range', () => { + let discussion; + let startCode; + let endCode; + + beforeEach(() => { + createPinia({ stubActions: false }); + + const file = getDiffFileMock(); + diffsStore.diffFiles = [file]; + + startCode = file.highlighted_diff_lines[6].line_code; + endCode = file.highlighted_diff_lines[7].line_code; + + discussion = { + ...discussionMock, + diff_file: file, + position: { + line_range: { + start: { + line_code: startCode, + }, + end: { + line_code: endCode, + }, + }, + }, + }; + + createWrapper({ discussion }); + }); + + it('passes the correct lines to the note body', () => { + const body = findNoteBody(); + + expect(body.props('lines')).toEqual([ + expect.objectContaining({ line_code: startCode }), + expect.objectContaining({ line_code: endCode }), + ]); + }); + }); }); describe('rendering', () => {