diff options
Diffstat (limited to 'spec/javascripts/notes')
-rw-r--r-- | spec/javascripts/notes/components/comment_form_spec.js | 23 | ||||
-rw-r--r-- | spec/javascripts/notes/components/diff_file_header_spec.js | 93 | ||||
-rw-r--r-- | spec/javascripts/notes/components/diff_with_note_spec.js | 64 | ||||
-rw-r--r-- | spec/javascripts/notes/components/note_app_spec.js | 5 | ||||
-rw-r--r-- | spec/javascripts/notes/components/note_body_spec.js | 27 | ||||
-rw-r--r-- | spec/javascripts/notes/components/note_header_spec.js | 32 | ||||
-rw-r--r-- | spec/javascripts/notes/mock_data.js | 5 | ||||
-rw-r--r-- | spec/javascripts/notes/stores/getters_spec.js | 4 | ||||
-rw-r--r-- | spec/javascripts/notes/stores/mutation_spec.js | 5 |
9 files changed, 232 insertions, 26 deletions
diff --git a/spec/javascripts/notes/components/comment_form_spec.js b/spec/javascripts/notes/components/comment_form_spec.js index 104d03377b6..6a7131528a3 100644 --- a/spec/javascripts/notes/components/comment_form_spec.js +++ b/spec/javascripts/notes/components/comment_form_spec.js @@ -1,17 +1,20 @@ import Vue from 'vue'; import Autosize from 'autosize'; import store from '~/notes/stores'; -import issueCommentForm from '~/notes/components/comment_form.vue'; +import CommentForm from '~/notes/components/comment_form.vue'; import { loggedOutnoteableData, notesDataMock, userDataMock, noteableDataMock } from '../mock_data'; import { keyboardDownEvent } from '../../issue_show/helpers'; describe('issue_comment_form component', () => { let vm; - const Component = Vue.extend(issueCommentForm); + const Component = Vue.extend(CommentForm); let mountComponent; beforeEach(() => { - mountComponent = () => new Component({ + mountComponent = (noteableType = 'issue') => new Component({ + propsData: { + noteableType, + }, store, }).$mount(); }); @@ -136,6 +139,11 @@ describe('issue_comment_form component', () => { expect(vm.editCurrentUserLastNote).toHaveBeenCalled(); }); + + it('inits autosave', () => { + expect(vm.autosave).toBeDefined(); + expect(vm.autosave.key).toEqual(`autosave/Note/Issue/${noteableDataMock.id}`); + }); }); describe('event enter', () => { @@ -182,6 +190,15 @@ describe('issue_comment_form component', () => { done(); }); }); + + it('updates button text with noteable type', (done) => { + vm.noteableType = 'merge_request'; + + Vue.nextTick(() => { + expect(vm.$el.querySelector('.btn-comment-and-close').textContent.trim()).toEqual('Close merge request'); + done(); + }); + }); }); describe('issue is confidential', () => { diff --git a/spec/javascripts/notes/components/diff_file_header_spec.js b/spec/javascripts/notes/components/diff_file_header_spec.js new file mode 100644 index 00000000000..aed30a087a6 --- /dev/null +++ b/spec/javascripts/notes/components/diff_file_header_spec.js @@ -0,0 +1,93 @@ +import Vue from 'vue'; +import DiffFileHeader from '~/notes/components/diff_file_header.vue'; +import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils'; +import mountComponent from '../../helpers/vue_mount_component_helper'; + +const discussionFixture = 'merge_requests/diff_discussion.json'; + +describe('diff_file_header', () => { + let vm; + const diffDiscussionMock = getJSONFixture(discussionFixture)[0]; + const diffFile = convertObjectPropsToCamelCase(diffDiscussionMock.diff_file); + const props = { + diffFile, + }; + const Component = Vue.extend(DiffFileHeader); + const selectors = { + get copyButton() { + return vm.$el.querySelector('button[data-original-title="Copy file path to clipboard"]'); + }, + get fileName() { + return vm.$el.querySelector('.file-title-name'); + }, + get titleWrapper() { + return vm.$refs.titleWrapper; + }, + }; + + describe('submodule', () => { + beforeEach(() => { + props.diffFile.submodule = true; + props.diffFile.submoduleLink = '<a href="/bha">Submodule</a>'; + + vm = mountComponent(Component, props); + }); + + it('shows submoduleLink', () => { + expect(selectors.fileName.innerHTML).toBe(props.diffFile.submoduleLink); + }); + + it('has button to copy blob path', () => { + expect(selectors.copyButton).toExist(); + expect(selectors.copyButton.getAttribute('data-clipboard-text')).toBe(props.diffFile.submoduleLink); + }); + }); + + describe('changed file', () => { + beforeEach(() => { + props.diffFile.submodule = false; + props.diffFile.discussionPath = 'some/discussion/id'; + + vm = mountComponent(Component, props); + }); + + it('shows file type icon', () => { + expect(vm.$el.innerHTML).toContain('fa-file-text-o'); + }); + + it('links to discussion path', () => { + expect(selectors.titleWrapper).toExist(); + expect(selectors.titleWrapper.tagName).toBe('A'); + expect(selectors.titleWrapper.getAttribute('href')).toBe(props.diffFile.discussionPath); + }); + + it('shows plain title if no link given', () => { + props.diffFile.discussionPath = undefined; + vm = mountComponent(Component, props); + + expect(selectors.titleWrapper.tagName).not.toBe('A'); + expect(selectors.titleWrapper.href).toBeFalsy(); + }); + + it('has button to copy file path', () => { + expect(selectors.copyButton).toExist(); + expect(selectors.copyButton.getAttribute('data-clipboard-text')).toBe(props.diffFile.filePath); + }); + + it('shows file mode change', (done) => { + vm.diffFile = { + ...props.diffFile, + modeChanged: true, + aMode: '100755', + bMode: '100644', + }; + + Vue.nextTick(() => { + expect( + vm.$refs.fileMode.textContent.trim(), + ).toBe('100755 → 100644'); + done(); + }); + }); + }); +}); diff --git a/spec/javascripts/notes/components/diff_with_note_spec.js b/spec/javascripts/notes/components/diff_with_note_spec.js new file mode 100644 index 00000000000..7f1f4bf0bcd --- /dev/null +++ b/spec/javascripts/notes/components/diff_with_note_spec.js @@ -0,0 +1,64 @@ +import Vue from 'vue'; +import DiffWithNote from '~/notes/components/diff_with_note.vue'; +import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils'; +import mountComponent from '../../helpers/vue_mount_component_helper'; + +const discussionFixture = 'merge_requests/diff_discussion.json'; +const imageDiscussionFixture = 'merge_requests/image_diff_discussion.json'; + +describe('diff_with_note', () => { + let vm; + const diffDiscussionMock = getJSONFixture(discussionFixture)[0]; + const diffDiscussion = convertObjectPropsToCamelCase(diffDiscussionMock); + const Component = Vue.extend(DiffWithNote); + const props = { + discussion: diffDiscussion, + }; + const selectors = { + get container() { + return vm.$refs.fileHolder; + }, + get diffTable() { + return this.container.querySelector('.diff-content table'); + }, + get diffRows() { + return this.container.querySelectorAll('.diff-content .line_holder'); + }, + get noteRow() { + return this.container.querySelector('.diff-content .notes_holder'); + }, + }; + + describe('text diff', () => { + beforeEach(() => { + vm = mountComponent(Component, props); + }); + + it('shows text diff', () => { + expect(selectors.container).toHaveClass('text-file'); + expect(selectors.diffTable).toExist(); + }); + + it('shows diff lines', () => { + expect(selectors.diffRows.length).toBe(12); + }); + + it('shows notes row', () => { + expect(selectors.noteRow).toExist(); + }); + }); + + describe('image diff', () => { + beforeEach(() => { + const imageDiffDiscussionMock = getJSONFixture(imageDiscussionFixture)[0]; + props.discussion = convertObjectPropsToCamelCase(imageDiffDiscussionMock); + }); + + it('shows image diff', () => { + vm = mountComponent(Component, props); + + expect(selectors.container).toHaveClass('js-image-file'); + expect(selectors.diffTable).not.toExist(); + }); + }); +}); diff --git a/spec/javascripts/notes/components/note_app_spec.js b/spec/javascripts/notes/components/note_app_spec.js index 12d180137a0..e1c612f5100 100644 --- a/spec/javascripts/notes/components/note_app_spec.js +++ b/spec/javascripts/notes/components/note_app_spec.js @@ -24,6 +24,7 @@ describe('note_app', () => { beforeEach(() => { jasmine.addMatchers(vueMatchers); + $('body').attr('data-page', 'projects:merge_requests:show'); const IssueNotesApp = Vue.extend(notesApp); @@ -119,8 +120,8 @@ describe('note_app', () => { vm = mountComponent(); }); - it('should render loading icon', () => { - expect(vm).toIncludeElement('.js-loading'); + it('renders skeleton notes', () => { + expect(vm).toIncludeElement('.animation-container'); }); it('should render form', () => { diff --git a/spec/javascripts/notes/components/note_body_spec.js b/spec/javascripts/notes/components/note_body_spec.js index b42e7943b98..0ff804f0e55 100644 --- a/spec/javascripts/notes/components/note_body_spec.js +++ b/spec/javascripts/notes/components/note_body_spec.js @@ -30,17 +30,26 @@ describe('issue_note_body component', () => { expect(vm.$el.querySelector('.note-text').innerHTML).toEqual(note.note_html); }); - it('should be render form if user is editing', (done) => { - vm.isEditing = true; + it('should render awards list', () => { + expect(vm.$el.querySelector('.js-awards-block button [data-name="baseball"]')).not.toBeNull(); + expect(vm.$el.querySelector('.js-awards-block button [data-name="bath_tone3"]')).not.toBeNull(); + }); - Vue.nextTick(() => { - expect(vm.$el.querySelector('textarea.js-task-list-field')).toBeDefined(); - done(); + describe('isEditing', () => { + beforeEach((done) => { + vm.isEditing = true; + Vue.nextTick(done); }); - }); - it('should render awards list', () => { - expect(vm.$el.querySelector('.js-awards-block button [data-name="baseball"]')).toBeDefined(); - expect(vm.$el.querySelector('.js-awards-block button [data-name="bath_tone3"]')).toBeDefined(); + it('renders edit form', () => { + expect(vm.$el.querySelector('textarea.js-task-list-field')).not.toBeNull(); + }); + + it('adds autosave', () => { + const autosaveKey = `autosave/Note/${note.noteable_type}/${note.id}`; + + expect(vm.autosave).toExist(); + expect(vm.autosave.key).toEqual(autosaveKey); + }); }); }); diff --git a/spec/javascripts/notes/components/note_header_spec.js b/spec/javascripts/notes/components/note_header_spec.js index 16a76b11321..5636f8d1a9f 100644 --- a/spec/javascripts/notes/components/note_header_spec.js +++ b/spec/javascripts/notes/components/note_header_spec.js @@ -32,6 +32,7 @@ describe('note_header component', () => { createdAt: '2017-08-02T10:51:58.559Z', includeToggle: false, noteId: 1394, + expanded: true, }, }).$mount(); }); @@ -68,6 +69,7 @@ describe('note_header component', () => { createdAt: '2017-08-02T10:51:58.559Z', includeToggle: true, noteId: 1395, + expanded: true, }, }).$mount(); }); @@ -76,17 +78,35 @@ describe('note_header component', () => { expect(vm.$el.querySelector('.js-vue-toggle-button')).toBeDefined(); }); - it('should toggle the disucssion icon', (done) => { - expect( - vm.$el.querySelector('.js-vue-toggle-button i').classList.contains('fa-chevron-up'), - ).toEqual(true); + it('emits toggle event on click', (done) => { + spyOn(vm, '$emit'); vm.$el.querySelector('.js-vue-toggle-button').click(); Vue.nextTick(() => { + expect(vm.$emit).toHaveBeenCalledWith('toggleHandler'); + done(); + }); + }); + + it('renders up arrow when open', (done) => { + vm.expanded = true; + + Vue.nextTick(() => { + expect( + vm.$el.querySelector('.js-vue-toggle-button i').classList, + ).toContain('fa-chevron-up'); + done(); + }); + }); + + it('renders down arrow when closed', (done) => { + vm.expanded = false; + + Vue.nextTick(() => { expect( - vm.$el.querySelector('.js-vue-toggle-button i').classList.contains('fa-chevron-down'), - ).toEqual(true); + vm.$el.querySelector('.js-vue-toggle-button i').classList, + ).toContain('fa-chevron-down'); done(); }); }); diff --git a/spec/javascripts/notes/mock_data.js b/spec/javascripts/notes/mock_data.js index ccf4bd070c2..bf60cb12f52 100644 --- a/spec/javascripts/notes/mock_data.js +++ b/spec/javascripts/notes/mock_data.js @@ -7,8 +7,9 @@ export const notesDataMock = { notesPath: '/gitlab-org/gitlab-ce/noteable/issue/98/notes', quickActionsDocsPath: '/help/user/project/quick_actions', registerPath: '/users/sign_in?redirect_to_referer=yes#register-pane', - closeIssuePath: '/twitter/flight/issues/9.json?issue%5Bstate_event%5D=close', - reopenIssuePath: '/twitter/flight/issues/9.json?issue%5Bstate_event%5D=reopen', + totalNotes: 1, + closePath: '/twitter/flight/issues/9.json?issue%5Bstate_event%5D=close', + reopenPath: '/twitter/flight/issues/9.json?issue%5Bstate_event%5D=reopen', }; export const userDataMock = { diff --git a/spec/javascripts/notes/stores/getters_spec.js b/spec/javascripts/notes/stores/getters_spec.js index 919ffbfdef0..8b2a8d2cd7a 100644 --- a/spec/javascripts/notes/stores/getters_spec.js +++ b/spec/javascripts/notes/stores/getters_spec.js @@ -56,9 +56,9 @@ describe('Getters Notes Store', () => { }); }); - describe('issueState', () => { + describe('openState', () => { it('should return the issue state', () => { - expect(getters.issueState(state)).toEqual(noteableDataMock.state); + expect(getters.openState(state)).toEqual(noteableDataMock.state); }); }); }); diff --git a/spec/javascripts/notes/stores/mutation_spec.js b/spec/javascripts/notes/stores/mutation_spec.js index 22d99998a7d..e4baefc5bfc 100644 --- a/spec/javascripts/notes/stores/mutation_spec.js +++ b/spec/javascripts/notes/stores/mutation_spec.js @@ -1,7 +1,7 @@ import mutations from '~/notes/stores/mutations'; import { note, discussionMock, notesDataMock, userDataMock, noteableDataMock, individualNote } from '../mock_data'; -describe('Mutation Notes Store', () => { +describe('Notes Store mutations', () => { describe('ADD_NEW_NOTE', () => { let state; let noteData; @@ -103,7 +103,8 @@ describe('Mutation Notes Store', () => { }; mutations.SET_INITIAL_NOTES(state, [note]); - expect(state.notes).toEqual([note]); + expect(state.notes[0].id).toEqual(note.id); + expect(state.notes.length).toEqual(1); }); }); |