diff options
Diffstat (limited to 'spec/javascripts/notes')
-rw-r--r-- | spec/javascripts/notes/components/note_form_spec.js | 157 | ||||
-rw-r--r-- | spec/javascripts/notes/stores/getters_spec.js | 8 | ||||
-rw-r--r-- | spec/javascripts/notes/stores/mutation_spec.js | 17 |
3 files changed, 121 insertions, 61 deletions
diff --git a/spec/javascripts/notes/components/note_form_spec.js b/spec/javascripts/notes/components/note_form_spec.js index 5db20fd285f..7cc324cfe44 100644 --- a/spec/javascripts/notes/components/note_form_spec.js +++ b/spec/javascripts/notes/components/note_form_spec.js @@ -1,17 +1,15 @@ -import Vue from 'vue'; +import { shallowMount, createLocalVue } from '@vue/test-utils'; import createStore from '~/notes/stores'; -import issueNoteForm from '~/notes/components/note_form.vue'; +import NoteForm from '~/notes/components/note_form.vue'; +import MarkdownField from '~/vue_shared/components/markdown/field.vue'; import { noteableDataMock, notesDataMock } from '../mock_data'; -import { keyboardDownEvent } from '../../issue_show/helpers'; describe('issue_note_form component', () => { let store; - let vm; + let wrapper; let props; beforeEach(() => { - const Component = Vue.extend(issueNoteForm); - store = createStore(); store.dispatch('setNoteableData', noteableDataMock); store.dispatch('setNotesData', notesDataMock); @@ -22,26 +20,35 @@ describe('issue_note_form component', () => { noteId: '545', }; - vm = new Component({ + const localVue = createLocalVue(); + wrapper = shallowMount(NoteForm, { store, propsData: props, - }).$mount(); + // see https://gitlab.com/gitlab-org/gitlab-ce/issues/56317 for the following + localVue, + sync: false, + }); }); afterEach(() => { - vm.$destroy(); + wrapper.destroy(); }); describe('noteHash', () => { it('returns note hash string based on `noteId`', () => { - expect(vm.noteHash).toBe(`#note_${props.noteId}`); + expect(wrapper.vm.noteHash).toBe(`#note_${props.noteId}`); }); it('return note hash as `#` when `noteId` is empty', done => { - vm.noteId = ''; - Vue.nextTick() + wrapper.setProps({ + ...props, + noteId: '', + }); + + wrapper.vm + .$nextTick() .then(() => { - expect(vm.noteHash).toBe('#'); + expect(wrapper.vm.noteHash).toBe('#'); }) .then(done) .catch(done.fail); @@ -50,95 +57,127 @@ describe('issue_note_form component', () => { describe('conflicts editing', () => { it('should show conflict message if note changes outside the component', done => { - vm.isEditing = true; - vm.noteBody = 'Foo'; + wrapper.setProps({ + ...props, + isEditing: true, + noteBody: 'Foo', + }); + const message = 'This comment has changed since you started editing, please review the updated comment to ensure information is not lost.'; - Vue.nextTick(() => { - expect( - vm.$el - .querySelector('.js-conflict-edit-warning') - .textContent.replace(/\s+/g, ' ') - .trim(), - ).toEqual(message); - done(); - }); + wrapper.vm + .$nextTick() + .then(() => { + const conflictWarning = wrapper.find('.js-conflict-edit-warning'); + + expect(conflictWarning.exists()).toBe(true); + expect( + conflictWarning + .text() + .replace(/\s+/g, ' ') + .trim(), + ).toBe(message); + }) + .then(done) + .catch(done.fail); }); }); describe('form', () => { it('should render text area with placeholder', () => { - expect(vm.$el.querySelector('textarea').getAttribute('placeholder')).toEqual( + const textarea = wrapper.find('textarea'); + + expect(textarea.attributes('placeholder')).toEqual( 'Write a comment or drag your files hereā¦', ); }); it('should link to markdown docs', () => { const { markdownDocsPath } = notesDataMock; + const markdownField = wrapper.find(MarkdownField); + const markdownFieldProps = markdownField.props(); - expect(vm.$el.querySelector(`a[href="${markdownDocsPath}"]`).textContent.trim()).toEqual( - 'Markdown', - ); + expect(markdownFieldProps.markdownDocsPath).toBe(markdownDocsPath); }); describe('keyboard events', () => { + let textarea; + + beforeEach(() => { + textarea = wrapper.find('textarea'); + textarea.setValue('Foo'); + }); + describe('up', () => { it('should ender edit mode', () => { - spyOn(vm, 'editMyLastNote').and.callThrough(); - vm.$el.querySelector('textarea').value = 'Foo'; - vm.$el.querySelector('textarea').dispatchEvent(keyboardDownEvent(38, true)); + // TODO: do not spy on vm + spyOn(wrapper.vm, 'editMyLastNote').and.callThrough(); + + textarea.trigger('keydown.up'); - expect(vm.editMyLastNote).toHaveBeenCalled(); + expect(wrapper.vm.editMyLastNote).toHaveBeenCalled(); }); }); describe('enter', () => { it('should save note when cmd+enter is pressed', () => { - spyOn(vm, 'handleUpdate').and.callThrough(); - vm.$el.querySelector('textarea').value = 'Foo'; - vm.$el.querySelector('textarea').dispatchEvent(keyboardDownEvent(13, true)); + textarea.trigger('keydown.enter', { metaKey: true }); + + const { handleFormUpdate } = wrapper.emitted(); - expect(vm.handleUpdate).toHaveBeenCalled(); + expect(handleFormUpdate.length).toBe(1); }); it('should save note when ctrl+enter is pressed', () => { - spyOn(vm, 'handleUpdate').and.callThrough(); - vm.$el.querySelector('textarea').value = 'Foo'; - vm.$el.querySelector('textarea').dispatchEvent(keyboardDownEvent(13, false, true)); + textarea.trigger('keydown.enter', { ctrlKey: true }); - expect(vm.handleUpdate).toHaveBeenCalled(); + const { handleFormUpdate } = wrapper.emitted(); + + expect(handleFormUpdate.length).toBe(1); }); }); }); describe('actions', () => { it('should be possible to cancel', done => { - spyOn(vm, 'cancelHandler').and.callThrough(); - vm.isEditing = true; + // TODO: do not spy on vm + spyOn(wrapper.vm, 'cancelHandler').and.callThrough(); + wrapper.setProps({ + ...props, + isEditing: true, + }); - Vue.nextTick(() => { - vm.$el.querySelector('.note-edit-cancel').click(); + wrapper.vm + .$nextTick() + .then(() => { + const cancelButton = wrapper.find('.note-edit-cancel'); + cancelButton.trigger('click'); - Vue.nextTick(() => { - expect(vm.cancelHandler).toHaveBeenCalled(); - done(); - }); - }); + expect(wrapper.vm.cancelHandler).toHaveBeenCalled(); + }) + .then(done) + .catch(done.fail); }); it('should be possible to update the note', done => { - vm.isEditing = true; - - Vue.nextTick(() => { - vm.$el.querySelector('textarea').value = 'Foo'; - vm.$el.querySelector('.js-vue-issue-save').click(); - - Vue.nextTick(() => { - expect(vm.isSubmitting).toEqual(true); - done(); - }); + wrapper.setProps({ + ...props, + isEditing: true, }); + + wrapper.vm + .$nextTick() + .then(() => { + const textarea = wrapper.find('textarea'); + textarea.setValue('Foo'); + const saveButton = wrapper.find('.js-vue-issue-save'); + saveButton.trigger('click'); + + expect(wrapper.vm.isSubmitting).toEqual(true); + }) + .then(done) + .catch(done.fail); }); }); }); diff --git a/spec/javascripts/notes/stores/getters_spec.js b/spec/javascripts/notes/stores/getters_spec.js index c066975a43b..8f3c493dd4c 100644 --- a/spec/javascripts/notes/stores/getters_spec.js +++ b/spec/javascripts/notes/stores/getters_spec.js @@ -261,4 +261,12 @@ describe('Getters Notes Store', () => { expect(getters.firstUnresolvedDiscussionId(state, localGettersFalsy)(false)).toBeFalsy(); }); }); + + describe('getDiscussion', () => { + it('returns discussion by ID', () => { + state.discussions.push({ id: '1' }); + + expect(getters.getDiscussion(state)('1')).toEqual({ id: '1' }); + }); + }); }); diff --git a/spec/javascripts/notes/stores/mutation_spec.js b/spec/javascripts/notes/stores/mutation_spec.js index fcad1f245b6..4a640d589fb 100644 --- a/spec/javascripts/notes/stores/mutation_spec.js +++ b/spec/javascripts/notes/stores/mutation_spec.js @@ -1,5 +1,6 @@ import Vue from 'vue'; import mutations from '~/notes/stores/mutations'; +import { DISCUSSION_NOTE } from '~/notes/constants'; import { note, discussionMock, @@ -326,6 +327,18 @@ describe('Notes Store mutations', () => { expect(state.discussions[0].notes[0].note).toEqual('Foo'); }); + + it('transforms an individual note to discussion', () => { + const state = { + discussions: [individualNote], + }; + + const transformedNote = { ...individualNote.notes[0], type: DISCUSSION_NOTE }; + + mutations.UPDATE_NOTE(state, transformedNote); + + expect(state.discussions[0].individual_note).toEqual(false); + }); }); describe('CLOSE_ISSUE', () => { @@ -530,7 +543,7 @@ describe('Notes Store mutations', () => { state = { convertedDisscussionIds: [] }; }); - it('adds a disucssion to convertedDisscussionIds', () => { + it('adds a discussion to convertedDisscussionIds', () => { mutations.CONVERT_TO_DISCUSSION(state, discussion.id); expect(state.convertedDisscussionIds).toContain(discussion.id); @@ -549,7 +562,7 @@ describe('Notes Store mutations', () => { state = { convertedDisscussionIds: [41, 42] }; }); - it('removes a disucssion from convertedDisscussionIds', () => { + it('removes a discussion from convertedDisscussionIds', () => { mutations.REMOVE_CONVERTED_DISCUSSION(state, discussion.id); expect(state.convertedDisscussionIds).not.toContain(discussion.id); |