diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-01-22 12:08:40 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-01-22 12:08:40 +0000 |
commit | be3e24ea3c9f497efde85900df298ce9bc42fce8 (patch) | |
tree | fd0de9443253a1b21ca9a2741dc34ba3aef795be /spec/frontend/notes | |
parent | 001243986195143c395a9811d8254bbf1b9ebfa1 (diff) | |
download | gitlab-ce-be3e24ea3c9f497efde85900df298ce9bc42fce8.tar.gz |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec/frontend/notes')
3 files changed, 171 insertions, 186 deletions
diff --git a/spec/frontend/notes/components/discussion_filter_note_spec.js b/spec/frontend/notes/components/discussion_filter_note_spec.js index 6b5f42a84e8..4701108d315 100644 --- a/spec/frontend/notes/components/discussion_filter_note_spec.js +++ b/spec/frontend/notes/components/discussion_filter_note_spec.js @@ -1,93 +1,40 @@ -import Vue from 'vue'; +import { shallowMount } from '@vue/test-utils'; import DiscussionFilterNote from '~/notes/components/discussion_filter_note.vue'; import eventHub from '~/notes/event_hub'; -import mountComponent from '../../helpers/vue_mount_component_helper'; - describe('DiscussionFilterNote component', () => { - let vm; + let wrapper; const createComponent = () => { - const Component = Vue.extend(DiscussionFilterNote); - - return mountComponent(Component); + wrapper = shallowMount(DiscussionFilterNote); }; beforeEach(() => { - vm = createComponent(); + createComponent(); }); afterEach(() => { - vm.$destroy(); + wrapper.destroy(); + wrapper = null; }); - describe('computed', () => { - describe('timelineContent', () => { - it('returns string containing instruction for switching feed type', () => { - expect(vm.timelineContent).toBe( - "You're only seeing <b>other activity</b> in the feed. To add a comment, switch to one of the following options.", - ); - }); - }); + it('timelineContent renders a string containing instruction for switching feed type', () => { + expect(wrapper.find({ ref: 'timelineContent' }).html()).toBe( + "<div>You're only seeing <b>other activity</b> in the feed. To add a comment, switch to one of the following options.</div>", + ); }); - describe('methods', () => { - describe('selectFilter', () => { - it('emits `dropdownSelect` event on `eventHub` with provided param', () => { - jest.spyOn(eventHub, '$emit').mockImplementation(() => {}); + it('emits `dropdownSelect` event with 0 parameter on clicking Show all activity button', () => { + jest.spyOn(eventHub, '$emit').mockImplementation(() => {}); + wrapper.find({ ref: 'showAllActivity' }).vm.$emit('click'); - vm.selectFilter(1); - - expect(eventHub.$emit).toHaveBeenCalledWith('dropdownSelect', 1); - }); - }); + expect(eventHub.$emit).toHaveBeenCalledWith('dropdownSelect', 0); }); - describe('template', () => { - it('renders component container element', () => { - expect(vm.$el.classList.contains('discussion-filter-note')).toBe(true); - }); - - it('renders comment icon element', () => { - expect(vm.$el.querySelector('.timeline-icon svg use').getAttribute('xlink:href')).toContain( - 'comment', - ); - }); - - it('renders filter information note', () => { - expect(vm.$el.querySelector('.timeline-content').innerText.trim()).toContain( - "You're only seeing other activity in the feed. To add a comment, switch to one of the following options.", - ); - }); - - it('renders filter buttons', () => { - const buttonsContainerEl = vm.$el.querySelector('.discussion-filter-actions'); - - expect(buttonsContainerEl.querySelector('button:first-child').innerText.trim()).toContain( - 'Show all activity', - ); - - expect(buttonsContainerEl.querySelector('button:last-child').innerText.trim()).toContain( - 'Show comments only', - ); - }); - - it('clicking `Show all activity` button calls `selectFilter("all")` method', () => { - const showAllBtn = vm.$el.querySelector('.discussion-filter-actions button:first-child'); - jest.spyOn(vm, 'selectFilter').mockImplementation(() => {}); - - showAllBtn.dispatchEvent(new Event('click')); - - expect(vm.selectFilter).toHaveBeenCalledWith(0); - }); - - it('clicking `Show comments only` button calls `selectFilter("comments")` method', () => { - const showAllBtn = vm.$el.querySelector('.discussion-filter-actions button:last-child'); - jest.spyOn(vm, 'selectFilter').mockImplementation(() => {}); - - showAllBtn.dispatchEvent(new Event('click')); + it('emits `dropdownSelect` event with 1 parameter on clicking Show comments only button', () => { + jest.spyOn(eventHub, '$emit').mockImplementation(() => {}); + wrapper.find({ ref: 'showComments' }).vm.$emit('click'); - expect(vm.selectFilter).toHaveBeenCalledWith(1); - }); + expect(eventHub.$emit).toHaveBeenCalledWith('dropdownSelect', 1); }); }); diff --git a/spec/frontend/notes/components/note_attachment_spec.js b/spec/frontend/notes/components/note_attachment_spec.js index b14a518b622..9d1051676e1 100644 --- a/spec/frontend/notes/components/note_attachment_spec.js +++ b/spec/frontend/notes/components/note_attachment_spec.js @@ -1,23 +1,45 @@ -import Vue from 'vue'; -import noteAttachment from '~/notes/components/note_attachment.vue'; - -describe('issue note attachment', () => { - it('should render properly', () => { - const props = { - attachment: { - filename: 'dk.png', - image: true, - url: '/dk.png', +import { shallowMount } from '@vue/test-utils'; +import NoteAttachment from '~/notes/components/note_attachment.vue'; + +describe('Issue note attachment', () => { + let wrapper; + + const findImage = () => wrapper.find({ ref: 'attachmentImage' }); + const findUrl = () => wrapper.find({ ref: 'attachmentUrl' }); + + const createComponent = attachment => { + wrapper = shallowMount(NoteAttachment, { + propsData: { + attachment, }, - }; + }); + }; + + afterEach(() => { + wrapper.destroy(); + wrapper = null; + }); + + it('renders attachment image if it is passed in attachment prop', () => { + createComponent({ + image: 'test-image', + }); + + expect(findImage().exists()).toBe(true); + }); + + it('renders attachment url if it is passed in attachment prop', () => { + createComponent({ + url: 'test-url', + }); + + expect(findUrl().exists()).toBe(true); + }); - const Component = Vue.extend(noteAttachment); - const vm = new Component({ - propsData: props, - }).$mount(); + it('does not render image and url if attachment object is empty', () => { + createComponent({}); - expect(vm.$el.classList.contains('note-attachment')).toBeTruthy(); - expect(vm.$el.querySelector('img').src).toContain(props.attachment.url); - expect(vm.$el.querySelector('a').href).toContain(props.attachment.url); + expect(findImage().exists()).toBe(false); + expect(findUrl().exists()).toBe(false); }); }); diff --git a/spec/frontend/notes/components/note_header_spec.js b/spec/frontend/notes/components/note_header_spec.js index 9b432387654..6544ad3e1fe 100644 --- a/spec/frontend/notes/components/note_header_spec.js +++ b/spec/frontend/notes/components/note_header_spec.js @@ -1,125 +1,141 @@ -import Vue from 'vue'; -import noteHeader from '~/notes/components/note_header.vue'; -import createStore from '~/notes/stores'; - -describe('note_header component', () => { - let store; - let vm; - let Component; - - beforeEach(() => { - Component = Vue.extend(noteHeader); - store = createStore(); - }); +import { shallowMount, createLocalVue } from '@vue/test-utils'; +import Vuex from 'vuex'; +import NoteHeader from '~/notes/components/note_header.vue'; + +const localVue = createLocalVue(); +localVue.use(Vuex); + +const actions = { + setTargetNoteHash: jest.fn(), +}; + +describe('NoteHeader component', () => { + let wrapper; + + const findActionsWrapper = () => wrapper.find({ ref: 'discussionActions' }); + const findChevronIcon = () => wrapper.find({ ref: 'chevronIcon' }); + const findActionText = () => wrapper.find({ ref: 'actionText' }); + const findTimestamp = () => wrapper.find({ ref: 'noteTimestamp' }); + + const createComponent = props => { + wrapper = shallowMount(NoteHeader, { + localVue, + store: new Vuex.Store({ + actions, + }), + propsData: { + ...props, + actionTextHtml: '', + noteId: '1394', + }, + }); + }; afterEach(() => { - vm.$destroy(); + wrapper.destroy(); + wrapper = null; }); - describe('individual note', () => { - beforeEach(() => { - vm = new Component({ - store, - propsData: { - actionText: 'commented', - actionTextHtml: '', - author: { - avatar_url: null, - id: 1, - name: 'Root', - path: '/root', - state: 'active', - username: 'root', - }, - createdAt: '2017-08-02T10:51:58.559Z', - includeToggle: false, - noteId: '1394', - expanded: true, - }, - }).$mount(); + it('does not render discussion actions when includeToggle is false', () => { + createComponent({ + includeToggle: false, }); - it('should render user information', () => { - expect(vm.$el.querySelector('.note-header-author-name').textContent.trim()).toEqual('Root'); - expect(vm.$el.querySelector('.note-header-info a').getAttribute('href')).toEqual('/root'); - expect(vm.$el.querySelector('.note-header-info a').dataset.userId).toEqual('1'); - expect(vm.$el.querySelector('.note-header-info a').dataset.username).toEqual('root'); - expect(vm.$el.querySelector('.note-header-info a').classList).toContain('js-user-link'); + expect(findActionsWrapper().exists()).toBe(false); + }); + + describe('when includes a toggle', () => { + it('renders discussion actions', () => { + createComponent({ + includeToggle: true, + }); + + expect(findActionsWrapper().exists()).toBe(true); }); - it('should render timestamp link', () => { - expect(vm.$el.querySelector('a[href="#note_1394"]')).toBeDefined(); + it('emits toggleHandler event on button click', () => { + createComponent({ + includeToggle: true, + }); + + wrapper.find('.note-action-button').trigger('click'); + expect(wrapper.emitted('toggleHandler')).toBeDefined(); + expect(wrapper.emitted('toggleHandler')).toHaveLength(1); }); - it('should not render user information when prop `author` is empty object', done => { - vm.author = {}; - Vue.nextTick() - .then(() => { - expect(vm.$el.querySelector('.note-header-author-name')).toBeNull(); - }) - .then(done) - .catch(done.fail); + it('has chevron-up icon if expanded prop is true', () => { + createComponent({ + includeToggle: true, + expanded: true, + }); + + expect(findChevronIcon().classes()).toContain('fa-chevron-up'); }); - }); - describe('discussion', () => { - beforeEach(() => { - vm = new Component({ - store, - propsData: { - actionText: 'started a discussion', - actionTextHtml: '', - author: { - avatar_url: null, - id: 1, - name: 'Root', - path: '/root', - state: 'active', - username: 'root', - }, - createdAt: '2017-08-02T10:51:58.559Z', - includeToggle: true, - noteId: '1395', - expanded: true, - }, - }).$mount(); + it('has chevron-down icon if expanded prop is false', () => { + createComponent({ + includeToggle: true, + expanded: false, + }); + + expect(findChevronIcon().classes()).toContain('fa-chevron-down'); }); + }); - it('should render toggle button', () => { - expect(vm.$el.querySelector('.js-vue-toggle-button')).toBeDefined(); + it('renders an author link if author is passed to props', () => { + createComponent({ + author: { + avatar_url: null, + id: 1, + name: 'Root', + path: '/root', + state: 'active', + username: 'root', + }, }); - it('emits toggle event on click', done => { - jest.spyOn(vm, '$emit').mockImplementation(() => {}); + expect(wrapper.find('.js-user-link').exists()).toBe(true); + }); - vm.$el.querySelector('.js-vue-toggle-button').click(); + it('renders deleted user text if author is not passed as a prop', () => { + createComponent(); - Vue.nextTick(() => { - expect(vm.$emit).toHaveBeenCalledWith('toggleHandler'); - done(); - }); - }); + expect(wrapper.text()).toContain('A deleted user'); + }); + + it('does not render created at information if createdAt is not passed as a prop', () => { + createComponent(); - it('renders up arrow when open', done => { - vm.expanded = true; + expect(findActionText().exists()).toBe(false); + expect(findTimestamp().exists()).toBe(false); + }); - Vue.nextTick(() => { - expect(vm.$el.querySelector('.js-vue-toggle-button i').classList).toContain( - 'fa-chevron-up', - ); - done(); + describe('when createdAt is passed as a prop', () => { + it('renders action text and a timestamp', () => { + createComponent({ + createdAt: '2017-08-02T10:51:58.559Z', }); + + expect(findActionText().exists()).toBe(true); + expect(findTimestamp().exists()).toBe(true); }); - it('renders down arrow when closed', done => { - vm.expanded = false; + it('renders correct actionText if passed', () => { + createComponent({ + createdAt: '2017-08-02T10:51:58.559Z', + actionText: 'Test action text', + }); + + expect(findActionText().text()).toBe('Test action text'); + }); - Vue.nextTick(() => { - expect(vm.$el.querySelector('.js-vue-toggle-button i').classList).toContain( - 'fa-chevron-down', - ); - done(); + it('calls an action when timestamp is clicked', () => { + createComponent({ + createdAt: '2017-08-02T10:51:58.559Z', }); + findTimestamp().trigger('click'); + + expect(actions.setTargetNoteHash).toHaveBeenCalled(); }); }); }); |