diff options
Diffstat (limited to 'spec/frontend/notes/components')
-rw-r--r-- | spec/frontend/notes/components/discussion_actions_spec.js | 14 | ||||
-rw-r--r-- | spec/frontend/notes/components/discussion_filter_spec.js | 5 | ||||
-rw-r--r-- | spec/frontend/notes/components/discussion_navigator_spec.js (renamed from spec/frontend/notes/components/discussion_keyboard_navigator_spec.js) | 38 | ||||
-rw-r--r-- | spec/frontend/notes/components/discussion_notes_spec.js | 47 | ||||
-rw-r--r-- | spec/frontend/notes/components/discussion_resolve_with_issue_button_spec.js | 4 | ||||
-rw-r--r-- | spec/frontend/notes/components/note_actions_spec.js | 2 | ||||
-rw-r--r-- | spec/frontend/notes/components/note_awards_list_spec.js | 2 | ||||
-rw-r--r-- | spec/frontend/notes/components/noteable_discussion_spec.js | 21 | ||||
-rw-r--r-- | spec/frontend/notes/components/noteable_note_spec.js | 38 |
9 files changed, 141 insertions, 30 deletions
diff --git a/spec/frontend/notes/components/discussion_actions_spec.js b/spec/frontend/notes/components/discussion_actions_spec.js index 44dc148933c..3e1e43d0c6a 100644 --- a/spec/frontend/notes/components/discussion_actions_spec.js +++ b/spec/frontend/notes/components/discussion_actions_spec.js @@ -21,7 +21,7 @@ const createUnallowedNote = () => describe('DiscussionActions', () => { let wrapper; - const createComponentFactory = (shallow = true) => props => { + const createComponentFactory = (shallow = true) => (props, options) => { const store = createStore(); const mountFn = shallow ? shallowMount : mount; @@ -35,6 +35,11 @@ describe('DiscussionActions', () => { shouldShowJumpToNextDiscussion: true, ...props, }, + provide: { + glFeatures: { + hideJumpToNextUnresolvedInThreads: options?.hideJumpToNextUnresolvedInThreads, + }, + }, }); }; @@ -96,6 +101,13 @@ describe('DiscussionActions', () => { }); }); + it('does not render jump to next discussion button if feature flag is enabled', () => { + const createComponent = createComponentFactory(); + createComponent({}, { hideJumpToNextUnresolvedInThreads: true }); + + expect(wrapper.find(JumpToNextDiscussionButton).exists()).toBe(false); + }); + describe('events handling', () => { const createComponent = createComponentFactory(false); diff --git a/spec/frontend/notes/components/discussion_filter_spec.js b/spec/frontend/notes/components/discussion_filter_spec.js index 7f042c0e9de..9a7896475e6 100644 --- a/spec/frontend/notes/components/discussion_filter_spec.js +++ b/spec/frontend/notes/components/discussion_filter_spec.js @@ -1,8 +1,8 @@ -import createEventHub from '~/helpers/event_hub_factory'; import Vuex from 'vuex'; - import { createLocalVue, mount } from '@vue/test-utils'; import AxiosMockAdapter from 'axios-mock-adapter'; +import { TEST_HOST } from 'jest/helpers/test_constants'; +import createEventHub from '~/helpers/event_hub_factory'; import axios from '~/lib/utils/axios_utils'; import notesModule from '~/notes/stores/modules'; @@ -10,7 +10,6 @@ import DiscussionFilter from '~/notes/components/discussion_filter.vue'; import { DISCUSSION_FILTERS_DEFAULT_VALUE, DISCUSSION_FILTER_TYPES } from '~/notes/constants'; import { discussionFiltersMock, discussionMock } from '../mock_data'; -import { TEST_HOST } from 'jest/helpers/test_constants'; const localVue = createLocalVue(); diff --git a/spec/frontend/notes/components/discussion_keyboard_navigator_spec.js b/spec/frontend/notes/components/discussion_navigator_spec.js index e932133b869..122814b8e3f 100644 --- a/spec/frontend/notes/components/discussion_keyboard_navigator_spec.js +++ b/spec/frontend/notes/components/discussion_navigator_spec.js @@ -1,9 +1,11 @@ /* global Mousetrap */ import 'mousetrap'; +import Vue from 'vue'; import { shallowMount, createLocalVue } from '@vue/test-utils'; -import DiscussionKeyboardNavigator from '~/notes/components/discussion_keyboard_navigator.vue'; +import DiscussionNavigator from '~/notes/components/discussion_navigator.vue'; +import eventHub from '~/notes/event_hub'; -describe('notes/components/discussion_keyboard_navigator', () => { +describe('notes/components/discussion_navigator', () => { const localVue = createLocalVue(); let wrapper; @@ -11,7 +13,7 @@ describe('notes/components/discussion_keyboard_navigator', () => { let jumpToPreviousDiscussion; const createComponent = () => { - wrapper = shallowMount(DiscussionKeyboardNavigator, { + wrapper = shallowMount(DiscussionNavigator, { mixins: [ localVue.extend({ methods: { @@ -29,10 +31,29 @@ describe('notes/components/discussion_keyboard_navigator', () => { }); afterEach(() => { - wrapper.destroy(); + if (wrapper) { + wrapper.destroy(); + } wrapper = null; }); + describe('on create', () => { + let onSpy; + let vm; + + beforeEach(() => { + onSpy = jest.spyOn(eventHub, '$on'); + vm = new (Vue.extend(DiscussionNavigator))(); + }); + + it('listens for jumpToFirstUnresolvedDiscussion events', () => { + expect(onSpy).toHaveBeenCalledWith( + 'jumpToFirstUnresolvedDiscussion', + vm.jumpToFirstUnresolvedDiscussion, + ); + }); + }); + describe('on mount', () => { beforeEach(() => { createComponent(); @@ -52,11 +73,16 @@ describe('notes/components/discussion_keyboard_navigator', () => { }); describe('on destroy', () => { + let jumpFn; + beforeEach(() => { jest.spyOn(Mousetrap, 'unbind'); + jest.spyOn(eventHub, '$off'); createComponent(); + jumpFn = wrapper.vm.jumpToFirstUnresolvedDiscussion; + wrapper.destroy(); }); @@ -65,6 +91,10 @@ describe('notes/components/discussion_keyboard_navigator', () => { expect(Mousetrap.unbind).toHaveBeenCalledWith('p'); }); + it('unbinds event hub listeners', () => { + expect(eventHub.$off).toHaveBeenCalledWith('jumpToFirstUnresolvedDiscussion', jumpFn); + }); + it('does not call jumpToNextDiscussion when pressing `n`', () => { Mousetrap.trigger('n'); diff --git a/spec/frontend/notes/components/discussion_notes_spec.js b/spec/frontend/notes/components/discussion_notes_spec.js index 5a10deefd09..8cc98f978c2 100644 --- a/spec/frontend/notes/components/discussion_notes_spec.js +++ b/spec/frontend/notes/components/discussion_notes_spec.js @@ -1,4 +1,5 @@ import { shallowMount } from '@vue/test-utils'; +import { getByRole } from '@testing-library/dom'; import '~/behaviors/markdown/render_gfm'; import { SYSTEM_NOTE } from '~/notes/constants'; import DiscussionNotes from '~/notes/components/discussion_notes.vue'; @@ -9,14 +10,20 @@ import SystemNote from '~/vue_shared/components/notes/system_note.vue'; import createStore from '~/notes/stores'; import { noteableDataMock, discussionMock, notesDataMock } from '../mock_data'; +const LINE_RANGE = {}; +const DISCUSSION_WITH_LINE_RANGE = { + ...discussionMock, + position: { + line_range: LINE_RANGE, + }, +}; + describe('DiscussionNotes', () => { + let store; let wrapper; - const createComponent = props => { - const store = createStore(); - store.dispatch('setNoteableData', noteableDataMock); - store.dispatch('setNotesData', notesDataMock); - + const getList = () => getByRole(wrapper.element, 'list'); + const createComponent = (props, features = {}) => { wrapper = shallowMount(DiscussionNotes, { store, propsData: { @@ -31,11 +38,21 @@ describe('DiscussionNotes', () => { slots: { 'avatar-badge': '<span class="avatar-badge-slot-content" />', }, + provide: { + glFeatures: { multilineComments: true, ...features }, + }, }); }; + beforeEach(() => { + store = createStore(); + store.dispatch('setNoteableData', noteableDataMock); + store.dispatch('setNotesData', notesDataMock); + }); + afterEach(() => { wrapper.destroy(); + wrapper = null; }); describe('rendering', () => { @@ -160,6 +177,26 @@ describe('DiscussionNotes', () => { }); }); + describe.each` + desc | props | features | event | expectedCalls + ${'with `discussion.position`'} | ${{ discussion: DISCUSSION_WITH_LINE_RANGE }} | ${{}} | ${'mouseenter'} | ${[['setSelectedCommentPositionHover', LINE_RANGE]]} + ${'with `discussion.position`'} | ${{ discussion: DISCUSSION_WITH_LINE_RANGE }} | ${{}} | ${'mouseleave'} | ${[['setSelectedCommentPositionHover']]} + ${'with `discussion.position`'} | ${{ discussion: DISCUSSION_WITH_LINE_RANGE }} | ${{ multilineComments: false }} | ${'mouseenter'} | ${[]} + ${'with `discussion.position`'} | ${{ discussion: DISCUSSION_WITH_LINE_RANGE }} | ${{ multilineComments: false }} | ${'mouseleave'} | ${[]} + ${'without `discussion.position`'} | ${{}} | ${{}} | ${'mouseenter'} | ${[]} + ${'without `discussion.position`'} | ${{}} | ${{}} | ${'mouseleave'} | ${[]} + `('$desc and features $features', ({ props, event, features, expectedCalls }) => { + beforeEach(() => { + createComponent(props, features); + jest.spyOn(store, 'dispatch'); + }); + + it(`calls store ${expectedCalls.length} times on ${event}`, () => { + getList().dispatchEvent(new MouseEvent(event)); + expect(store.dispatch.mock.calls).toEqual(expectedCalls); + }); + }); + describe('componentData', () => { beforeEach(() => { createComponent(); diff --git a/spec/frontend/notes/components/discussion_resolve_with_issue_button_spec.js b/spec/frontend/notes/components/discussion_resolve_with_issue_button_spec.js index e62fb5db2c0..4348445f7ca 100644 --- a/spec/frontend/notes/components/discussion_resolve_with_issue_button_spec.js +++ b/spec/frontend/notes/components/discussion_resolve_with_issue_button_spec.js @@ -1,4 +1,4 @@ -import { GlDeprecatedButton } from '@gitlab/ui'; +import { GlButton } from '@gitlab/ui'; import { shallowMount, createLocalVue } from '@vue/test-utils'; import { TEST_HOST } from 'spec/test_constants'; import ResolveWithIssueButton from '~/notes/components/discussion_resolve_with_issue_button.vue'; @@ -23,7 +23,7 @@ describe('ResolveWithIssueButton', () => { }); it('it should have a link with the provided link property as href', () => { - const button = wrapper.find(GlDeprecatedButton); + const button = wrapper.find(GlButton); expect(button.attributes().href).toBe(url); }); diff --git a/spec/frontend/notes/components/note_actions_spec.js b/spec/frontend/notes/components/note_actions_spec.js index 5cc56cdefae..97d1752726b 100644 --- a/spec/frontend/notes/components/note_actions_spec.js +++ b/spec/frontend/notes/components/note_actions_spec.js @@ -1,10 +1,10 @@ import Vue from 'vue'; import { shallowMount, createLocalVue, createWrapper } from '@vue/test-utils'; import { TEST_HOST } from 'spec/test_constants'; +import AxiosMockAdapter from 'axios-mock-adapter'; import createStore from '~/notes/stores'; import noteActions from '~/notes/components/note_actions.vue'; import { userDataMock } from '../mock_data'; -import AxiosMockAdapter from 'axios-mock-adapter'; import axios from '~/lib/utils/axios_utils'; describe('noteActions', () => { diff --git a/spec/frontend/notes/components/note_awards_list_spec.js b/spec/frontend/notes/components/note_awards_list_spec.js index 822b1f9efce..dce5424f154 100644 --- a/spec/frontend/notes/components/note_awards_list_spec.js +++ b/spec/frontend/notes/components/note_awards_list_spec.js @@ -1,10 +1,10 @@ import Vue from 'vue'; import AxiosMockAdapter from 'axios-mock-adapter'; +import { TEST_HOST } from 'jest/helpers/test_constants'; 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; diff --git a/spec/frontend/notes/components/noteable_discussion_spec.js b/spec/frontend/notes/components/noteable_discussion_spec.js index b14ec2a65be..1c6603899d3 100644 --- a/spec/frontend/notes/components/noteable_discussion_spec.js +++ b/spec/frontend/notes/components/noteable_discussion_spec.js @@ -1,4 +1,6 @@ import { mount, createLocalVue } from '@vue/test-utils'; +import mockDiffFile from 'jest/diffs/mock_data/diff_file'; +import { trimText } from 'helpers/text_helper'; import createStore from '~/notes/stores'; import noteableDiscussion from '~/notes/components/noteable_discussion.vue'; import ReplyPlaceholder from '~/notes/components/discussion_reply_placeholder.vue'; @@ -12,8 +14,6 @@ import { loggedOutnoteableData, userDataMock, } from '../mock_data'; -import mockDiffFile from 'jest/diffs/mock_data/diff_file'; -import { trimText } from 'helpers/text_helper'; const discussionWithTwoUnresolvedNotes = 'merge_requests/resolved_diff_discussion.json'; @@ -89,6 +89,23 @@ describe('noteable_discussion component', () => { }); }); + it('should expand discussion', async () => { + const expandDiscussion = jest.fn(); + const discussion = { ...discussionMock }; + discussion.expanded = false; + + wrapper.setProps({ discussion }); + wrapper.setMethods({ expandDiscussion }); + + await wrapper.vm.$nextTick(); + + wrapper.vm.showReplyForm(); + + await wrapper.vm.$nextTick(); + + expect(expandDiscussion).toHaveBeenCalledWith({ discussionId: discussion.id }); + }); + it('does not render jump to thread button', () => { expect(wrapper.find('*[data-original-title="Jump to next unresolved thread"]').exists()).toBe( false, diff --git a/spec/frontend/notes/components/noteable_note_spec.js b/spec/frontend/notes/components/noteable_note_spec.js index fc238feb974..a08e86d92d3 100644 --- a/spec/frontend/notes/components/noteable_note_spec.js +++ b/spec/frontend/notes/components/noteable_note_spec.js @@ -83,18 +83,34 @@ describe('issue_note', () => { }); }); - it('should render multiline comment if editing discussion root', () => { - wrapper.setProps({ discussionRoot: true }); - wrapper.vm.isEditing = true; - - return wrapper.vm.$nextTick().then(() => { - expect(findMultilineComment().exists()).toBe(true); + it('should only render if it has everything it needs', () => { + const position = { + line_range: { + start: { + line_code: 'abc_1_1', + type: null, + old_line: '', + new_line: '', + }, + end: { + line_code: 'abc_2_2', + type: null, + old_line: '2', + new_line: '2', + }, + }, + }; + const line = { + line_code: 'abc_1_1', + type: null, + old_line: '1', + new_line: '1', + }; + wrapper.setProps({ + note: { ...note, position }, + discussionRoot: true, + line, }); - }); - - it('should not render multiline comment form unless it is the discussion root', () => { - wrapper.setProps({ discussionRoot: false }); - wrapper.vm.isEditing = true; return wrapper.vm.$nextTick().then(() => { expect(findMultilineComment().exists()).toBe(false); |