Commit 43e4988e authored by Brian T's avatar Brian T Committed by Phil Hughes

Fix award emoji tooltip being escaped twice if multiple people voted

parent ad290106
......@@ -116,16 +116,20 @@ export default {
// We have 10+ awarded user, join them with comma and add `and x more`.
if (remainingAwardList.length) {
title = sprintf(__(`%{listToShow}, and %{awardsListLength} more.`), {
title = sprintf(
__(`%{listToShow}, and %{awardsListLength} more.`),
{
listToShow: namesToShow.join(', '),
awardsListLength: remainingAwardList.length,
});
},
false,
);
} else if (namesToShow.length > 1) {
// Join all names with comma but not the last one, it will be added with and text.
title = namesToShow.slice(0, namesToShow.length - 1).join(', ');
// If we have more than 2 users we need an extra comma before and text.
title += namesToShow.length > 2 ? ',' : '';
title += sprintf(__(` and %{sliced}`), { sliced: namesToShow.slice(-1) }); // Append and text
title += sprintf(__(` and %{sliced}`), { sliced: namesToShow.slice(-1) }, false); // Append and text
} else {
// We have only 2 users so join them with and.
title = namesToShow.join(__(' and '));
......
---
title: Fix award emoji tooltip being escaped twice if multiple people voted
merge_request: 19273
author: Brian T
type: fixed
......@@ -61,6 +61,66 @@ describe('note_awards_list component', () => {
expect(vm.$el.querySelector('.js-add-award')).toBeDefined();
});
describe('when the user name contains special HTML characters', () => {
const createAwardEmoji = (_, index) => ({
name: 'art',
user: { id: index, name: `&<>"\`'-${index}`, username: `user-${index}` },
});
const mountComponent = () => {
const Component = Vue.extend(awardsNote);
vm = new Component({
store,
propsData: {
awards: awardsMock,
noteAuthorId: 0,
noteId: '545',
canAwardEmoji: true,
toggleAwardPath: '/gitlab-org/gitlab-foss/notes/545/toggle_award_emoji',
},
}).$mount();
};
const findTooltip = () =>
vm.$el.querySelector('[data-original-title]').getAttribute('data-original-title');
it('should only escape & and " characters', () => {
awardsMock = [...new Array(1)].map(createAwardEmoji);
mountComponent();
const escapedName = awardsMock[0].user.name.replace(/&/g, '&amp;').replace(/"/g, '&quot;');
expect(vm.$el.querySelector('[data-original-title]').outerHTML).toContain(escapedName);
});
it('should not escape special HTML characters twice when only 1 person awarded', () => {
awardsMock = [...new Array(1)].map(createAwardEmoji);
mountComponent();
awardsMock.forEach(award => {
expect(findTooltip()).toContain(award.user.name);
});
});
it('should not escape special HTML characters twice when 2 people awarded', () => {
awardsMock = [...new Array(2)].map(createAwardEmoji);
mountComponent();
awardsMock.forEach(award => {
expect(findTooltip()).toContain(award.user.name);
});
});
it('should not escape special HTML characters twice when more than 10 people awarded', () => {
awardsMock = [...new Array(11)].map(createAwardEmoji);
mountComponent();
// Testing only the first 10 awards since 11 onward will not be displayed.
awardsMock.slice(0, 10).forEach(award => {
expect(findTooltip()).toContain(award.user.name);
});
});
});
describe('when the user cannot award emoji', () => {
beforeEach(() => {
const Component = Vue.extend(awardsNote);
......
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