Skip to content
Snippets Groups Projects
Unverified Commit 7632330e authored by Fatih Acet's avatar Fatih Acet
Browse files

Fix showing outdated discussions on Changes tab

parent 489025bb
No related branches found
No related tags found
No related merge requests found
Showing
with 146 additions and 20 deletions
Loading
Loading
@@ -77,7 +77,8 @@ export default {
diffViewType: state => state.diffs.diffViewType,
diffFiles: state => state.diffs.diffFiles,
}),
...mapGetters(['isLoggedIn', 'discussionsByLineCode']),
...mapGetters(['isLoggedIn']),
...mapGetters('diffs', ['discussionsByLineCode']),
lineHref() {
return this.lineCode ? `#${this.lineCode}` : '#';
},
Loading
Loading
Loading
Loading
@@ -26,13 +26,16 @@ export default {
...mapState({
diffLineCommentForms: state => state.diffs.diffLineCommentForms,
}),
...mapGetters(['discussionsByLineCode']),
...mapGetters('diffs', ['discussionsByLineCode']),
discussions() {
return this.discussionsByLineCode[this.line.lineCode] || [];
},
className() {
return this.discussions.length ? '' : 'js-temp-notes-holder';
},
hasCommentForm() {
return this.diffLineCommentForms[this.line.lineCode];
},
},
};
</script>
Loading
Loading
@@ -53,7 +56,7 @@ export default {
:discussions="discussions"
/>
<diff-line-note-form
v-if="diffLineCommentForms[line.lineCode]"
v-if="hasCommentForm"
:diff-file-hash="diffFileHash"
:line="line"
:note-target-line="line"
Loading
Loading
Loading
Loading
@@ -20,8 +20,7 @@ export default {
},
},
computed: {
...mapGetters('diffs', ['commitId']),
...mapGetters(['discussionsByLineCode']),
...mapGetters('diffs', ['commitId', 'discussionsByLineCode']),
...mapState({
diffLineCommentForms: state => state.diffs.diffLineCommentForms,
}),
Loading
Loading
Loading
Loading
@@ -26,7 +26,7 @@ export default {
...mapState({
diffLineCommentForms: state => state.diffs.diffLineCommentForms,
}),
...mapGetters(['discussionsByLineCode']),
...mapGetters('diffs', ['discussionsByLineCode']),
leftLineCode() {
return this.line.left.lineCode;
},
Loading
Loading
Loading
Loading
@@ -21,8 +21,7 @@ export default {
},
},
computed: {
...mapGetters('diffs', ['commitId']),
...mapGetters(['discussionsByLineCode']),
...mapGetters('diffs', ['commitId', 'discussionsByLineCode']),
...mapState({
diffLineCommentForms: state => state.diffs.diffLineCommentForms,
}),
Loading
Loading
import _ from 'underscore';
import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
import { PARALLEL_DIFF_VIEW_TYPE, INLINE_DIFF_VIEW_TYPE } from '../constants';
import { getDiffRefsByLineCode } from './utils';
 
export const isParallelView = state => state.diffViewType === PARALLEL_DIFF_VIEW_TYPE;
 
Loading
Loading
@@ -56,6 +58,44 @@ export const getDiffFileDiscussions = (state, getters, rootState, rootGetters) =
discussion.diff_discussion && _.isEqual(discussion.diff_file.file_hash, diff.fileHash),
) || [];
 
/**
* Returns an Object with discussions by their diff line code
* To avoid rendering outdated discussions on the Changes tab we should do a bunch of SHA
* comparisions. `note.position.formatter` have the current version diff refs but
* `note.original_position.formatter` will have the first version's diff refs.
* If line diff refs matches with one of them, we should render it as a discussion on Changes tab.
*
* @param {Object} diff
* @returns {Array}
*/
export const discussionsByLineCode = (state, getters, rootState, rootGetters) => {
const diffRefsByLineCode = getDiffRefsByLineCode(state.diffFiles);
return rootGetters.discussions.reduce((acc, note) => {
const isDiffDiscussion = note.diff_discussion;
const hasLineCode = note.line_code;
const isResolvable = note.resolvable;
const diffRefs = diffRefsByLineCode[note.line_code];
if (isDiffDiscussion && hasLineCode && isResolvable && diffRefs) {
const refs = convertObjectPropsToCamelCase(note.position.formatter);
const originalRefs = convertObjectPropsToCamelCase(note.original_position.formatter);
if (_.isEqual(refs, diffRefs) || _.isEqual(originalRefs, diffRefs)) {
const lineCode = note.line_code;
if (acc[lineCode]) {
acc[lineCode].push(note);
} else {
acc[lineCode] = [note];
}
}
}
return acc;
}, {});
};
// prevent babel-plugin-rewire from generating an invalid default during karma∂ tests
export const getDiffFileByHash = state => fileHash =>
state.diffFiles.find(file => file.fileHash === fileHash);
Loading
Loading
Loading
Loading
@@ -173,3 +173,24 @@ export function trimFirstCharOfLineContent(line = {}) {
 
return parsedLine;
}
export function getDiffRefsByLineCode(diffFiles) {
return diffFiles.reduce((acc, diffFile) => {
const { baseSha, headSha, startSha } = diffFile.diffRefs;
const { newPath, oldPath } = diffFile;
// We can only use highlightedDiffLines to create the map of diff lines because
// highlightedDiffLines will also include every parallel diff line in it.
if (diffFile.highlightedDiffLines) {
diffFile.highlightedDiffLines.forEach(line => {
const { lineCode, oldLine, newLine } = line;
if (lineCode) {
acc[lineCode] = { baseSha, headSha, startSha, newPath, oldPath, oldLine, newLine };
}
});
}
return acc;
}, {});
}
Loading
Loading
@@ -28,18 +28,6 @@ export const notesById = state =>
return acc;
}, {});
 
export const discussionsByLineCode = state =>
state.discussions.reduce((acc, note) => {
if (note.diff_discussion && note.line_code && note.resolvable) {
// For context about line notes: there might be multiple notes with the same line code
const items = acc[note.line_code] || [];
items.push(note);
Object.assign(acc, { [note.line_code]: items });
}
return acc;
}, {});
export const noteableType = state => {
const { ISSUE_NOTEABLE_TYPE, MERGE_REQUEST_NOTEABLE_TYPE, EPIC_NOTEABLE_TYPE } = constants;
 
Loading
Loading
Loading
Loading
@@ -4,6 +4,7 @@ class DiscussionEntity < Grape::Entity
 
expose :id, :reply_id
expose :position, if: -> (d, _) { d.diff_discussion? && !d.legacy_diff_discussion? }
expose :original_position, if: -> (d, _) { d.diff_discussion? && !d.legacy_diff_discussion? }
expose :line_code, if: -> (d, _) { d.diff_discussion? }
expose :expanded?, as: :expanded
expose :active?, as: :active, if: -> (d, _) { d.diff_discussion? }
Loading
Loading
---
title: Fix showing outdated discussions on Changes tab
merge_request: 20445
author:
type: fixed
Loading
Loading
@@ -18,10 +18,12 @@ describe('DiffLineGutterContent', () => {
};
const setDiscussions = component => {
component.$store.dispatch('setInitialNotes', getDiscussionsMockData());
component.$store.commit('diffs/SET_DIFF_DATA', { diffFiles: [getDiffFileMock()] });
};
 
const resetDiscussions = component => {
component.$store.dispatch('setInitialNotes', []);
component.$store.commit('diffs/SET_DIFF_DATA', {});
};
 
describe('computed', () => {
Loading
Loading
Loading
Loading
@@ -33,6 +33,7 @@ describe('InlineDiffView', () => {
it('should render discussions', done => {
const el = component.$el;
component.$store.dispatch('setInitialNotes', getDiscussionsMockData());
component.$store.commit('diffs/SET_DIFF_DATA', { diffFiles: [getDiffFileMock()] });
 
Vue.nextTick(() => {
expect(el.querySelectorAll('.notes_holder').length).toEqual(1);
Loading
Loading
Loading
Loading
@@ -12,6 +12,17 @@ export default {
head_sha: 'c48ee0d1bf3b30453f5b32250ce03134beaa6d13',
},
},
original_position: {
formatter: {
old_line: null,
new_line: 2,
old_path: 'CHANGELOG',
new_path: 'CHANGELOG',
base_sha: 'e63f41fe459e62e1228fcef60d7189127aeba95a',
start_sha: 'd9eaefe5a676b820c57ff18cf5b68316025f7962',
head_sha: 'c48ee0d1bf3b30453f5b32250ce03134beaa6d13',
},
},
line_code: '1c497fbb3a46b78edf04cc2a2fa33f67e3ffbe2a_1_2',
expanded: true,
notes: [
Loading
Loading
Loading
Loading
@@ -2,6 +2,7 @@ import * as getters from '~/diffs/store/getters';
import state from '~/diffs/store/modules/diff_state';
import { PARALLEL_DIFF_VIEW_TYPE, INLINE_DIFF_VIEW_TYPE } from '~/diffs/constants';
import discussion from '../mock_data/diff_discussions';
import diffFile from '../mock_data/diff_file';
 
describe('Diffs Module Getters', () => {
let localState;
Loading
Loading
@@ -203,4 +204,38 @@ describe('Diffs Module Getters', () => {
expect(getters.getDiffFileByHash(localState)('123')).toBeUndefined();
});
});
describe('discussionsByLineCode', () => {
let mockState;
beforeEach(() => {
mockState = { diffFiles: [diffFile] };
});
it('should return a map of diff lines with their line codes', () => {
const mockGetters = { discussions: [discussionMock] };
const map = getters.discussionsByLineCode(mockState, {}, {}, mockGetters);
expect(map['1c497fbb3a46b78edf04cc2a2fa33f67e3ffbe2a_1_2']).toBeDefined();
expect(Object.keys(map).length).toEqual(1);
});
it('should have the diff discussion on the map if the original position matches', () => {
discussionMock.position.formatter.base_sha = 'ff9200';
const mockGetters = { discussions: [discussionMock] };
const map = getters.discussionsByLineCode(mockState, {}, {}, mockGetters);
expect(map['1c497fbb3a46b78edf04cc2a2fa33f67e3ffbe2a_1_2']).toBeDefined();
expect(Object.keys(map).length).toEqual(1);
});
it('should not add an outdated diff discussion to the returned map', () => {
discussionMock.position.formatter.base_sha = 'ff9200';
discussionMock.original_position.formatter.base_sha = 'ff9200';
const mockGetters = { discussions: [discussionMock] };
const map = getters.discussionsByLineCode(mockState, {}, {}, mockGetters);
expect(Object.keys(map).length).toEqual(0);
});
});
});
Loading
Loading
@@ -207,4 +207,24 @@ describe('DiffsStoreUtils', () => {
expect(utils.trimFirstCharOfLineContent()).toEqual({});
});
});
describe('getDiffRefsByLineCode', () => {
it('should return diffRefs for all highlightedDiffLines', () => {
const diffFile = getDiffFileMock();
const map = utils.getDiffRefsByLineCode([diffFile]);
const { highlightedDiffLines } = diffFile;
const lineCodeCount = highlightedDiffLines.reduce(
(acc, line) => (line.lineCode ? acc + 1 : acc),
0,
);
const { baseSha, headSha, startSha } = diffFile.diffRefs;
const targetLine = map[highlightedDiffLines[4].lineCode];
expect(Object.keys(map).length).toEqual(lineCodeCount);
expect(targetLine.baseSha).toEqual(baseSha);
expect(targetLine.headSha).toEqual(headSha);
expect(targetLine.startSha).toEqual(startSha);
});
});
});
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment