diff options
Diffstat (limited to 'spec/javascripts/notes')
7 files changed, 112 insertions, 194 deletions
diff --git a/spec/javascripts/notes/components/discussion_reply_placeholder_spec.js b/spec/javascripts/notes/components/discussion_reply_placeholder_spec.js deleted file mode 100644 index 07a366cf339..00000000000 --- a/spec/javascripts/notes/components/discussion_reply_placeholder_spec.js +++ /dev/null @@ -1,34 +0,0 @@ -import ReplyPlaceholder from '~/notes/components/discussion_reply_placeholder.vue'; -import { shallowMount, createLocalVue } from '@vue/test-utils'; - -const localVue = createLocalVue(); - -describe('ReplyPlaceholder', () => { - let wrapper; - - beforeEach(() => { - wrapper = shallowMount(ReplyPlaceholder, { - localVue, - }); - }); - - afterEach(() => { - wrapper.destroy(); - }); - - it('emits onClick even on button click', () => { - const button = wrapper.find({ ref: 'button' }); - - button.trigger('click'); - - expect(wrapper.emitted()).toEqual({ - onClick: [[]], - }); - }); - - it('should render reply button', () => { - const button = wrapper.find({ ref: 'button' }); - - expect(button.text()).toEqual('Reply...'); - }); -}); diff --git a/spec/javascripts/notes/components/discussion_resolve_button_spec.js b/spec/javascripts/notes/components/discussion_resolve_button_spec.js deleted file mode 100644 index 5024f40ec5d..00000000000 --- a/spec/javascripts/notes/components/discussion_resolve_button_spec.js +++ /dev/null @@ -1,74 +0,0 @@ -import resolveDiscussionButton from '~/notes/components/discussion_resolve_button.vue'; -import { createLocalVue, shallowMount } from '@vue/test-utils'; - -const buttonTitle = 'Resolve discussion'; - -describe('resolveDiscussionButton', () => { - let wrapper; - let localVue; - - const factory = options => { - localVue = createLocalVue(); - wrapper = shallowMount(resolveDiscussionButton, { - localVue, - ...options, - }); - }; - - beforeEach(() => { - factory({ - propsData: { - isResolving: false, - buttonTitle, - }, - }); - }); - - afterEach(() => { - wrapper.destroy(); - }); - - it('should emit a onClick event on button click', () => { - const button = wrapper.find({ ref: 'button' }); - - button.trigger('click'); - - expect(wrapper.emitted()).toEqual({ - onClick: [[]], - }); - }); - - it('should contain the provided button title', () => { - const button = wrapper.find({ ref: 'button' }); - - expect(button.text()).toContain(buttonTitle); - }); - - it('should show a loading spinner while resolving', () => { - factory({ - propsData: { - isResolving: true, - buttonTitle, - }, - }); - - const button = wrapper.find({ ref: 'isResolvingIcon' }); - - expect(button.exists()).toEqual(true); - }); - - it('should only show a loading spinner while resolving', () => { - factory({ - propsData: { - isResolving: false, - buttonTitle, - }, - }); - - const button = wrapper.find({ ref: 'isResolvingIcon' }); - - localVue.nextTick(() => { - expect(button.exists()).toEqual(false); - }); - }); -}); diff --git a/spec/javascripts/notes/components/note_app_spec.js b/spec/javascripts/notes/components/note_app_spec.js index d716ece3766..ef876dc2941 100644 --- a/spec/javascripts/notes/components/note_app_spec.js +++ b/spec/javascripts/notes/components/note_app_spec.js @@ -192,9 +192,9 @@ describe('note_app', () => { expect(service.updateNote).toHaveBeenCalled(); // Wait for the requests to finish before destroying - Vue.nextTick() - .then(done) - .catch(done.fail); + setTimeout(() => { + done(); + }); }); }); @@ -227,9 +227,9 @@ describe('note_app', () => { expect(service.updateNote).toHaveBeenCalled(); // Wait for the requests to finish before destroying - Vue.nextTick() - .then(done) - .catch(done.fail); + setTimeout(() => { + done(); + }); }); }); }); diff --git a/spec/javascripts/notes/components/note_attachment_spec.js b/spec/javascripts/notes/components/note_attachment_spec.js deleted file mode 100644 index b14a518b622..00000000000 --- a/spec/javascripts/notes/components/note_attachment_spec.js +++ /dev/null @@ -1,23 +0,0 @@ -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', - }, - }; - - const Component = Vue.extend(noteAttachment); - const vm = new Component({ - propsData: props, - }).$mount(); - - 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); - }); -}); diff --git a/spec/javascripts/notes/components/note_edited_text_spec.js b/spec/javascripts/notes/components/note_edited_text_spec.js deleted file mode 100644 index e4c8d954d50..00000000000 --- a/spec/javascripts/notes/components/note_edited_text_spec.js +++ /dev/null @@ -1,47 +0,0 @@ -import Vue from 'vue'; -import noteEditedText from '~/notes/components/note_edited_text.vue'; - -describe('note_edited_text', () => { - let vm; - let props; - - beforeEach(() => { - const Component = Vue.extend(noteEditedText); - props = { - actionText: 'Edited', - className: 'foo-bar', - editedAt: '2017-08-04T09:52:31.062Z', - editedBy: { - avatar_url: 'path', - id: 1, - name: 'Root', - path: '/root', - state: 'active', - username: 'root', - }, - }; - - vm = new Component({ - propsData: props, - }).$mount(); - }); - - afterEach(() => { - vm.$destroy(); - }); - - it('should render block with provided className', () => { - expect(vm.$el.className).toEqual(props.className); - }); - - it('should render provided actionText', () => { - expect(vm.$el.textContent).toContain(props.actionText); - }); - - it('should render provided user information', () => { - const authorLink = vm.$el.querySelector('.js-user-link'); - - expect(authorLink.getAttribute('href')).toEqual(props.editedBy.path); - expect(authorLink.textContent.trim()).toEqual(props.editedBy.name); - }); -}); diff --git a/spec/javascripts/notes/components/note_form_spec.js b/spec/javascripts/notes/components/note_form_spec.js index 7cc324cfe44..b632ee6736d 100644 --- a/spec/javascripts/notes/components/note_form_spec.js +++ b/spec/javascripts/notes/components/note_form_spec.js @@ -5,11 +5,33 @@ import MarkdownField from '~/vue_shared/components/markdown/field.vue'; import { noteableDataMock, notesDataMock } from '../mock_data'; describe('issue_note_form component', () => { + const dummyAutosaveKey = 'some-autosave-key'; + const dummyDraft = 'dummy draft content'; + let store; let wrapper; let props; + const createComponentWrapper = () => { + const localVue = createLocalVue(); + return shallowMount(NoteForm, { + store, + propsData: props, + // see https://gitlab.com/gitlab-org/gitlab-ce/issues/56317 for the following + localVue, + sync: false, + }); + }; + beforeEach(() => { + spyOnDependency(NoteForm, 'getDraft').and.callFake(key => { + if (key === dummyAutosaveKey) { + return dummyDraft; + } + + return null; + }); + store = createStore(); store.dispatch('setNoteableData', noteableDataMock); store.dispatch('setNotesData', notesDataMock); @@ -19,15 +41,6 @@ describe('issue_note_form component', () => { noteBody: 'Magni suscipit eius consectetur enim et ex et commodi.', noteId: '545', }; - - const localVue = createLocalVue(); - wrapper = shallowMount(NoteForm, { - store, - propsData: props, - // see https://gitlab.com/gitlab-org/gitlab-ce/issues/56317 for the following - localVue, - sync: false, - }); }); afterEach(() => { @@ -35,6 +48,10 @@ describe('issue_note_form component', () => { }); describe('noteHash', () => { + beforeEach(() => { + wrapper = createComponentWrapper(); + }); + it('returns note hash string based on `noteId`', () => { expect(wrapper.vm.noteHash).toBe(`#note_${props.noteId}`); }); @@ -56,6 +73,10 @@ describe('issue_note_form component', () => { }); describe('conflicts editing', () => { + beforeEach(() => { + wrapper = createComponentWrapper(); + }); + it('should show conflict message if note changes outside the component', done => { wrapper.setProps({ ...props, @@ -85,6 +106,10 @@ describe('issue_note_form component', () => { }); describe('form', () => { + beforeEach(() => { + wrapper = createComponentWrapper(); + }); + it('should render text area with placeholder', () => { const textarea = wrapper.find('textarea'); @@ -181,4 +206,63 @@ describe('issue_note_form component', () => { }); }); }); + + describe('with autosaveKey', () => { + describe('with draft', () => { + beforeEach(done => { + Object.assign(props, { + noteBody: '', + autosaveKey: dummyAutosaveKey, + }); + wrapper = createComponentWrapper(); + + wrapper.vm + .$nextTick() + .then(done) + .catch(done.fail); + }); + + it('displays the draft in textarea', () => { + const textarea = wrapper.find('textarea'); + + expect(textarea.element.value).toBe(dummyDraft); + }); + }); + + describe('without draft', () => { + beforeEach(done => { + Object.assign(props, { + noteBody: '', + autosaveKey: 'some key without draft', + }); + wrapper = createComponentWrapper(); + + wrapper.vm + .$nextTick() + .then(done) + .catch(done.fail); + }); + + it('leaves the textarea empty', () => { + const textarea = wrapper.find('textarea'); + + expect(textarea.element.value).toBe(''); + }); + }); + + it('updates the draft if textarea content changes', () => { + const updateDraftSpy = spyOnDependency(NoteForm, 'updateDraft').and.stub(); + Object.assign(props, { + noteBody: '', + autosaveKey: dummyAutosaveKey, + }); + wrapper = createComponentWrapper(); + const textarea = wrapper.find('textarea'); + const dummyContent = 'some new content'; + + textarea.setValue(dummyContent); + + expect(updateDraftSpy).toHaveBeenCalledWith(dummyAutosaveKey, dummyContent); + }); + }); }); diff --git a/spec/javascripts/notes/components/noteable_discussion_spec.js b/spec/javascripts/notes/components/noteable_discussion_spec.js index 2b93fb9fb45..3304c79cdb7 100644 --- a/spec/javascripts/notes/components/noteable_discussion_spec.js +++ b/spec/javascripts/notes/components/noteable_discussion_spec.js @@ -3,6 +3,7 @@ import createStore from '~/notes/stores'; import noteableDiscussion from '~/notes/components/noteable_discussion.vue'; import ReplyPlaceholder from '~/notes/components/discussion_reply_placeholder.vue'; import ResolveWithIssueButton from '~/notes/components/discussion_resolve_with_issue_button.vue'; +import NoteForm from '~/notes/components/note_form.vue'; import '~/behaviors/markdown/render_gfm'; import { noteableDataMock, discussionMock, notesDataMock } from '../mock_data'; import mockDiffFile from '../../diffs/mock_data/diff_file'; @@ -72,7 +73,18 @@ describe('noteable_discussion component', () => { .then(() => wrapper.vm.$nextTick()) .then(() => { expect(wrapper.vm.isReplying).toEqual(true); - expect(wrapper.vm.$refs.noteForm).not.toBeNull(); + + const noteForm = wrapper.find(NoteForm); + + expect(noteForm.exists()).toBe(true); + + const noteFormProps = noteForm.props(); + + expect(noteFormProps.discussion).toBe(discussionMock); + expect(noteFormProps.isEditing).toBe(false); + expect(noteFormProps.line).toBe(null); + expect(noteFormProps.saveButtonTitle).toBe('Comment'); + expect(noteFormProps.autosaveKey).toBe(`Note/Issue/${discussionMock.id}/Reply`); }) .then(done) .catch(done.fail); |