diff options
Diffstat (limited to 'spec/frontend/notes/components/note_awards_list_spec.js')
-rw-r--r-- | spec/frontend/notes/components/note_awards_list_spec.js | 163 |
1 files changed, 163 insertions, 0 deletions
diff --git a/spec/frontend/notes/components/note_awards_list_spec.js b/spec/frontend/notes/components/note_awards_list_spec.js new file mode 100644 index 00000000000..822b1f9efce --- /dev/null +++ b/spec/frontend/notes/components/note_awards_list_spec.js @@ -0,0 +1,163 @@ +import Vue from 'vue'; +import AxiosMockAdapter from 'axios-mock-adapter'; +import axios from '~/lib/utils/axios_utils'; +import createStore from '~/notes/stores'; +import awardsNote from '~/notes/components/note_awards_list.vue'; +import { noteableDataMock, notesDataMock } from '../mock_data'; +import { TEST_HOST } from 'jest/helpers/test_constants'; + +describe('note_awards_list component', () => { + let store; + let vm; + let awardsMock; + let mock; + + const toggleAwardPath = `${TEST_HOST}/gitlab-org/gitlab-foss/notes/545/toggle_award_emoji`; + + beforeEach(() => { + mock = new AxiosMockAdapter(axios); + + mock.onPost(toggleAwardPath).reply(200, ''); + + const Component = Vue.extend(awardsNote); + + store = createStore(); + store.dispatch('setNoteableData', noteableDataMock); + store.dispatch('setNotesData', notesDataMock); + awardsMock = [ + { + name: 'flag_tz', + user: { id: 1, name: 'Administrator', username: 'root' }, + }, + { + name: 'cartwheel_tone3', + user: { id: 12, name: 'Bobbie Stehr', username: 'erin' }, + }, + ]; + + vm = new Component({ + store, + propsData: { + awards: awardsMock, + noteAuthorId: 2, + noteId: '545', + canAwardEmoji: true, + toggleAwardPath, + }, + }).$mount(); + }); + + afterEach(() => { + mock.restore(); + vm.$destroy(); + }); + + it('should render awarded emojis', () => { + expect(vm.$el.querySelector('.js-awards-block button [data-name="flag_tz"]')).toBeDefined(); + expect( + vm.$el.querySelector('.js-awards-block button [data-name="cartwheel_tone3"]'), + ).toBeDefined(); + }); + + it('should be possible to remove awarded emoji', () => { + jest.spyOn(vm, 'handleAward'); + jest.spyOn(vm, 'toggleAwardRequest'); + vm.$el.querySelector('.js-awards-block button').click(); + + expect(vm.handleAward).toHaveBeenCalledWith('flag_tz'); + expect(vm.toggleAwardRequest).toHaveBeenCalled(); + }); + + it('should be possible to add new emoji', () => { + 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, '&').replace(/"/g, '"'); + + 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); + + vm = new Component({ + store, + propsData: { + awards: awardsMock, + noteAuthorId: 2, + noteId: '545', + canAwardEmoji: false, + toggleAwardPath: '/gitlab-org/gitlab-foss/notes/545/toggle_award_emoji', + }, + }).$mount(); + }); + + it('should not be possible to remove awarded emoji', () => { + jest.spyOn(vm, 'toggleAwardRequest'); + + vm.$el.querySelector('.js-awards-block button').click(); + + expect(vm.toggleAwardRequest).not.toHaveBeenCalled(); + }); + + it('should not be possible to add new emoji', () => { + expect(vm.$el.querySelector('.js-add-award')).toBeNull(); + }); + }); +}); |