diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2022-02-18 12:45:46 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2022-02-18 12:45:46 +0300 |
commit | a7b3560714b4d9cc4ab32dffcd1f74a284b93580 (patch) | |
tree | 7452bd5c3545c2fa67a28aa013835fb4fa071baf /spec/frontend/notes | |
parent | ee9173579ae56a3dbfe5afe9f9410c65bb327ca7 (diff) |
Add latest changes from gitlab-org/gitlab@14-8-stable-eev14.8.0-rc42
Diffstat (limited to 'spec/frontend/notes')
18 files changed, 206 insertions, 281 deletions
diff --git a/spec/frontend/notes/components/comment_form_spec.js b/spec/frontend/notes/components/comment_form_spec.js index 16dbf60cef4..a605edc4357 100644 --- a/spec/frontend/notes/components/comment_form_spec.js +++ b/spec/frontend/notes/components/comment_form_spec.js @@ -20,7 +20,6 @@ import { loggedOutnoteableData, notesDataMock, userDataMock, noteableDataMock } jest.mock('autosize'); jest.mock('~/commons/nav/user_merge_requests'); jest.mock('~/flash'); -jest.mock('~/gl_form'); Vue.use(Vuex); @@ -466,8 +465,8 @@ describe('issue_comment_form component', () => { await findCloseReopenButton().trigger('click'); - await wrapper.vm.$nextTick; - await wrapper.vm.$nextTick; + await nextTick; + await nextTick; expect(createFlash).toHaveBeenCalledWith({ message: `Something went wrong while closing the ${type}. Please try again later.`, @@ -502,8 +501,8 @@ describe('issue_comment_form component', () => { await findCloseReopenButton().trigger('click'); - await wrapper.vm.$nextTick; - await wrapper.vm.$nextTick; + await nextTick; + await nextTick; expect(createFlash).toHaveBeenCalledWith({ message: `Something went wrong while reopening the ${type}. Please try again later.`, @@ -521,7 +520,7 @@ describe('issue_comment_form component', () => { await findCloseReopenButton().trigger('click'); - await wrapper.vm.$nextTick(); + await nextTick(); expect(refreshUserMergeRequestCounts).toHaveBeenCalled(); }); @@ -581,7 +580,7 @@ describe('issue_comment_form component', () => { // check checkbox checkbox.element.checked = shouldCheckboxBeChecked; checkbox.trigger('change'); - await wrapper.vm.$nextTick(); + await nextTick(); // submit comment findCommentButton().trigger('click'); diff --git a/spec/frontend/notes/components/diff_discussion_header_spec.js b/spec/frontend/notes/components/diff_discussion_header_spec.js index fa34a5e8d39..9f94dd693cb 100644 --- a/spec/frontend/notes/components/diff_discussion_header_spec.js +++ b/spec/frontend/notes/components/diff_discussion_header_spec.js @@ -1,5 +1,6 @@ import { mount } from '@vue/test-utils'; +import { nextTick } from 'vue'; import diffDiscussionHeader from '~/notes/components/diff_discussion_header.vue'; import createStore from '~/notes/stores'; @@ -24,16 +25,15 @@ describe('diff_discussion_header component', () => { wrapper.destroy(); }); - it('should render user avatar', () => { + it('should render user avatar', async () => { const discussion = { ...discussionMock }; discussion.diff_file = mockDiffFile; discussion.diff_discussion = true; wrapper.setProps({ discussion }); - return wrapper.vm.$nextTick().then(() => { - expect(wrapper.find('.user-avatar-link').exists()).toBe(true); - }); + await nextTick(); + expect(wrapper.find('.user-avatar-link').exists()).toBe(true); }); describe('action text', () => { @@ -41,7 +41,7 @@ describe('diff_discussion_header component', () => { const truncatedCommitId = commitId.substr(0, 8); let commitElement; - beforeEach((done) => { + beforeEach(async () => { store.state.diffs = { projectPath: 'something', }; @@ -58,41 +58,30 @@ describe('diff_discussion_header component', () => { }, }); - wrapper.vm - .$nextTick() - .then(() => { - commitElement = wrapper.find('.commit-sha'); - }) - .then(done) - .catch(done.fail); + await nextTick(); + commitElement = wrapper.find('.commit-sha'); }); describe('for diff threads without a commit id', () => { - it('should show started a thread on the diff text', (done) => { + it('should show started a thread on the diff text', async () => { Object.assign(wrapper.vm.discussion, { for_commit: false, commit_id: null, }); - wrapper.vm.$nextTick(() => { - expect(wrapper.text()).toContain('started a thread on the diff'); - - done(); - }); + await nextTick(); + expect(wrapper.text()).toContain('started a thread on the diff'); }); - it('should show thread on older version text', (done) => { + it('should show thread on older version text', async () => { Object.assign(wrapper.vm.discussion, { for_commit: false, commit_id: null, active: false, }); - wrapper.vm.$nextTick(() => { - expect(wrapper.text()).toContain('started a thread on an old version of the diff'); - - done(); - }); + await nextTick(); + expect(wrapper.text()).toContain('started a thread on an old version of the diff'); }); }); @@ -105,31 +94,25 @@ describe('diff_discussion_header component', () => { }); describe('for diff thread with a commit id', () => { - it('should display started thread on commit header', (done) => { + it('should display started thread on commit header', async () => { wrapper.vm.discussion.for_commit = false; - wrapper.vm.$nextTick(() => { - expect(wrapper.text()).toContain(`started a thread on commit ${truncatedCommitId}`); - - expect(commitElement).not.toBe(null); + await nextTick(); + expect(wrapper.text()).toContain(`started a thread on commit ${truncatedCommitId}`); - done(); - }); + expect(commitElement).not.toBe(null); }); - it('should display outdated change on commit header', (done) => { + it('should display outdated change on commit header', async () => { wrapper.vm.discussion.for_commit = false; wrapper.vm.discussion.active = false; - wrapper.vm.$nextTick(() => { - expect(wrapper.text()).toContain( - `started a thread on an outdated change in commit ${truncatedCommitId}`, - ); + await nextTick(); + expect(wrapper.text()).toContain( + `started a thread on an outdated change in commit ${truncatedCommitId}`, + ); - expect(commitElement).not.toBe(null); - - done(); - }); + expect(commitElement).not.toBe(null); }); }); }); diff --git a/spec/frontend/notes/components/discussion_counter_spec.js b/spec/frontend/notes/components/discussion_counter_spec.js index c454d502beb..a856d002d2e 100644 --- a/spec/frontend/notes/components/discussion_counter_spec.js +++ b/spec/frontend/notes/components/discussion_counter_spec.js @@ -1,5 +1,6 @@ import { GlButton } from '@gitlab/ui'; -import { shallowMount, createLocalVue } from '@vue/test-utils'; +import { shallowMount } from '@vue/test-utils'; +import Vue, { nextTick } from 'vue'; import Vuex from 'vuex'; import DiscussionCounter from '~/notes/components/discussion_counter.vue'; import notesModule from '~/notes/stores/modules'; @@ -10,9 +11,8 @@ describe('DiscussionCounter component', () => { let store; let wrapper; let setExpandDiscussionsFn; - const localVue = createLocalVue(); - localVue.use(Vuex); + Vue.use(Vuex); beforeEach(() => { window.mrTabs = {}; @@ -45,7 +45,7 @@ describe('DiscussionCounter component', () => { describe('has no discussions', () => { it('does not render', () => { - wrapper = shallowMount(DiscussionCounter, { store, localVue }); + wrapper = shallowMount(DiscussionCounter, { store }); expect(wrapper.find({ ref: 'discussionCounter' }).exists()).toBe(false); }); @@ -55,7 +55,7 @@ describe('DiscussionCounter component', () => { it('does not render', () => { store.commit(types.ADD_OR_UPDATE_DISCUSSIONS, [{ ...discussionMock, resolvable: false }]); store.dispatch('updateResolvableDiscussionsCounts'); - wrapper = shallowMount(DiscussionCounter, { store, localVue }); + wrapper = shallowMount(DiscussionCounter, { store }); expect(wrapper.find({ ref: 'discussionCounter' }).exists()).toBe(false); }); @@ -75,7 +75,7 @@ describe('DiscussionCounter component', () => { it('renders', () => { updateStore(); - wrapper = shallowMount(DiscussionCounter, { store, localVue }); + wrapper = shallowMount(DiscussionCounter, { store }); expect(wrapper.find({ ref: 'discussionCounter' }).exists()).toBe(true); }); @@ -86,7 +86,7 @@ describe('DiscussionCounter component', () => { ${'allResolved'} | ${true} | ${true} | ${1} `('renders correctly if $title', ({ resolved, isActive, groupLength }) => { updateStore({ resolvable: true, resolved }); - wrapper = shallowMount(DiscussionCounter, { store, localVue }); + wrapper = shallowMount(DiscussionCounter, { store }); expect(wrapper.find(`.is-active`).exists()).toBe(isActive); expect(wrapper.findAll(GlButton)).toHaveLength(groupLength); @@ -99,7 +99,7 @@ describe('DiscussionCounter component', () => { const discussion = { ...discussionMock, expanded }; store.commit(types.ADD_OR_UPDATE_DISCUSSIONS, [discussion]); store.dispatch('updateResolvableDiscussionsCounts'); - wrapper = shallowMount(DiscussionCounter, { store, localVue }); + wrapper = shallowMount(DiscussionCounter, { store }); toggleAllButton = wrapper.find('.toggle-all-discussions-btn'); }; @@ -113,7 +113,7 @@ describe('DiscussionCounter component', () => { expect(setExpandDiscussionsFn).toHaveBeenCalledTimes(1); }); - it('collapses all discussions if expanded', () => { + it('collapses all discussions if expanded', async () => { updateStoreWithExpanded(true); expect(wrapper.vm.allExpanded).toBe(true); @@ -121,13 +121,12 @@ describe('DiscussionCounter component', () => { toggleAllButton.vm.$emit('click'); - return wrapper.vm.$nextTick().then(() => { - expect(wrapper.vm.allExpanded).toBe(false); - expect(toggleAllButton.props('icon')).toBe('angle-down'); - }); + await nextTick(); + expect(wrapper.vm.allExpanded).toBe(false); + expect(toggleAllButton.props('icon')).toBe('angle-down'); }); - it('expands all discussions if collapsed', () => { + it('expands all discussions if collapsed', async () => { updateStoreWithExpanded(false); expect(wrapper.vm.allExpanded).toBe(false); @@ -135,10 +134,9 @@ describe('DiscussionCounter component', () => { toggleAllButton.vm.$emit('click'); - return wrapper.vm.$nextTick().then(() => { - expect(wrapper.vm.allExpanded).toBe(true); - expect(toggleAllButton.props('icon')).toBe('angle-up'); - }); + await nextTick(); + expect(wrapper.vm.allExpanded).toBe(true); + expect(toggleAllButton.props('icon')).toBe('angle-up'); }); }); }); diff --git a/spec/frontend/notes/components/discussion_filter_spec.js b/spec/frontend/notes/components/discussion_filter_spec.js index 17998dfc9d5..27206bddbfc 100644 --- a/spec/frontend/notes/components/discussion_filter_spec.js +++ b/spec/frontend/notes/components/discussion_filter_spec.js @@ -1,5 +1,6 @@ import { GlDropdown } from '@gitlab/ui'; -import { createLocalVue, mount } from '@vue/test-utils'; +import { mount } from '@vue/test-utils'; +import Vue, { nextTick } from 'vue'; import AxiosMockAdapter from 'axios-mock-adapter'; import Vuex from 'vuex'; import { TEST_HOST } from 'helpers/test_constants'; @@ -12,9 +13,7 @@ import notesModule from '~/notes/stores/modules'; import { discussionFiltersMock, discussionMock } from '../mock_data'; -const localVue = createLocalVue(); - -localVue.use(Vuex); +Vue.use(Vuex); const DISCUSSION_PATH = `${TEST_HOST}/example`; @@ -58,7 +57,6 @@ describe('DiscussionFilter component', () => { filters: discussionFiltersMock, selectedValue: DISCUSSION_FILTERS_DEFAULT_VALUE, }, - localVue, }); }; @@ -153,13 +151,11 @@ describe('DiscussionFilter component', () => { window.mrTabs = undefined; }); - it('only renders when discussion tab is active', (done) => { + it('only renders when discussion tab is active', async () => { eventHub.$emit('MergeRequestTabChange', 'commit'); - wrapper.vm.$nextTick(() => { - expect(wrapper.html()).toBe(''); - done(); - }); + await nextTick(); + expect(wrapper.html()).toBe(''); }); }); @@ -168,58 +164,48 @@ describe('DiscussionFilter component', () => { window.location.hash = ''; }); - it('updates the filter when the URL links to a note', (done) => { + it('updates the filter when the URL links to a note', async () => { window.location.hash = `note_${discussionMock.notes[0].id}`; wrapper.vm.currentValue = discussionFiltersMock[2].value; wrapper.vm.handleLocationHash(); - wrapper.vm.$nextTick(() => { - expect(wrapper.vm.currentValue).toBe(DISCUSSION_FILTERS_DEFAULT_VALUE); - done(); - }); + await nextTick(); + expect(wrapper.vm.currentValue).toBe(DISCUSSION_FILTERS_DEFAULT_VALUE); }); - it('does not update the filter when the current filter is "Show all activity"', (done) => { + it('does not update the filter when the current filter is "Show all activity"', async () => { window.location.hash = `note_${discussionMock.notes[0].id}`; wrapper.vm.handleLocationHash(); - wrapper.vm.$nextTick(() => { - expect(wrapper.vm.currentValue).toBe(DISCUSSION_FILTERS_DEFAULT_VALUE); - done(); - }); + await nextTick(); + expect(wrapper.vm.currentValue).toBe(DISCUSSION_FILTERS_DEFAULT_VALUE); }); - it('only updates filter when the URL links to a note', (done) => { + it('only updates filter when the URL links to a note', async () => { window.location.hash = `testing123`; wrapper.vm.handleLocationHash(); - wrapper.vm.$nextTick(() => { - expect(wrapper.vm.currentValue).toBe(DISCUSSION_FILTERS_DEFAULT_VALUE); - done(); - }); + await nextTick(); + expect(wrapper.vm.currentValue).toBe(DISCUSSION_FILTERS_DEFAULT_VALUE); }); - it('fetches discussions when there is a hash', (done) => { + it('fetches discussions when there is a hash', async () => { window.location.hash = `note_${discussionMock.notes[0].id}`; wrapper.vm.currentValue = discussionFiltersMock[2].value; jest.spyOn(wrapper.vm, 'selectFilter').mockImplementation(() => {}); wrapper.vm.handleLocationHash(); - wrapper.vm.$nextTick(() => { - expect(wrapper.vm.selectFilter).toHaveBeenCalled(); - done(); - }); + await nextTick(); + expect(wrapper.vm.selectFilter).toHaveBeenCalled(); }); - it('does not fetch discussions when there is no hash', (done) => { + it('does not fetch discussions when there is no hash', async () => { window.location.hash = ''; jest.spyOn(wrapper.vm, 'selectFilter').mockImplementation(() => {}); wrapper.vm.handleLocationHash(); - wrapper.vm.$nextTick(() => { - expect(wrapper.vm.selectFilter).not.toHaveBeenCalled(); - done(); - }); + await nextTick(); + expect(wrapper.vm.selectFilter).not.toHaveBeenCalled(); }); }); }); diff --git a/spec/frontend/notes/components/discussion_navigator_spec.js b/spec/frontend/notes/components/discussion_navigator_spec.js index e430e18b76a..77ae7b2c3b5 100644 --- a/spec/frontend/notes/components/discussion_navigator_spec.js +++ b/spec/frontend/notes/components/discussion_navigator_spec.js @@ -1,6 +1,6 @@ /* global Mousetrap */ import 'mousetrap'; -import { shallowMount, createLocalVue } from '@vue/test-utils'; +import { shallowMount } from '@vue/test-utils'; import Vue from 'vue'; import { keysFor, @@ -11,8 +11,6 @@ import DiscussionNavigator from '~/notes/components/discussion_navigator.vue'; import eventHub from '~/notes/event_hub'; describe('notes/components/discussion_navigator', () => { - const localVue = createLocalVue(); - let wrapper; let jumpToNextDiscussion; let jumpToPreviousDiscussion; @@ -20,12 +18,12 @@ describe('notes/components/discussion_navigator', () => { const createComponent = () => { wrapper = shallowMount(DiscussionNavigator, { mixins: [ - localVue.extend({ + { methods: { jumpToNextDiscussion, jumpToPreviousDiscussion, }, - }), + }, ], }); }; @@ -48,7 +46,7 @@ describe('notes/components/discussion_navigator', () => { beforeEach(() => { onSpy = jest.spyOn(eventHub, '$on'); - vm = new (Vue.extend(DiscussionNavigator))(); + vm = new Vue(DiscussionNavigator); }); it('listens for jumpToFirstUnresolvedDiscussion events', () => { diff --git a/spec/frontend/notes/components/discussion_notes_spec.js b/spec/frontend/notes/components/discussion_notes_spec.js index 59ac75f00e6..3506b6ac9f3 100644 --- a/spec/frontend/notes/components/discussion_notes_spec.js +++ b/spec/frontend/notes/components/discussion_notes_spec.js @@ -1,6 +1,7 @@ import { getByRole } from '@testing-library/dom'; import { shallowMount, mount } from '@vue/test-utils'; import '~/behaviors/markdown/render_gfm'; +import { nextTick } from 'vue'; import DiscussionNotes from '~/notes/components/discussion_notes.vue'; import NoteableNote from '~/notes/components/noteable_note.vue'; import { SYSTEM_NOTE } from '~/notes/constants'; @@ -135,28 +136,25 @@ describe('DiscussionNotes', () => { createComponent({ shouldGroupReplies: true, isExpanded: true }); }); - it('emits deleteNote when first note emits handleDeleteNote', () => { + it('emits deleteNote when first note emits handleDeleteNote', async () => { findNoteAtIndex(0).vm.$emit('handleDeleteNote'); - return wrapper.vm.$nextTick().then(() => { - expect(wrapper.emitted().deleteNote).toBeTruthy(); - }); + await nextTick(); + expect(wrapper.emitted().deleteNote).toBeTruthy(); }); - it('emits startReplying when first note emits startReplying', () => { + it('emits startReplying when first note emits startReplying', async () => { findNoteAtIndex(0).vm.$emit('startReplying'); - return wrapper.vm.$nextTick().then(() => { - expect(wrapper.emitted().startReplying).toBeTruthy(); - }); + await nextTick(); + expect(wrapper.emitted().startReplying).toBeTruthy(); }); - it('emits deleteNote when second note emits handleDeleteNote', () => { + it('emits deleteNote when second note emits handleDeleteNote', async () => { findNoteAtIndex(1).vm.$emit('handleDeleteNote'); - return wrapper.vm.$nextTick().then(() => { - expect(wrapper.emitted().deleteNote).toBeTruthy(); - }); + await nextTick(); + expect(wrapper.emitted().deleteNote).toBeTruthy(); }); }); @@ -167,12 +165,11 @@ describe('DiscussionNotes', () => { note = wrapper.find('.notes > *'); }); - it('emits deleteNote when first note emits handleDeleteNote', () => { + it('emits deleteNote when first note emits handleDeleteNote', async () => { note.vm.$emit('handleDeleteNote'); - return wrapper.vm.$nextTick().then(() => { - expect(wrapper.emitted().deleteNote).toBeTruthy(); - }); + await nextTick(); + expect(wrapper.emitted().deleteNote).toBeTruthy(); }); }); }); diff --git a/spec/frontend/notes/components/discussion_resolve_button_spec.js b/spec/frontend/notes/components/discussion_resolve_button_spec.js index 64e061830b9..ca0c0ca6de8 100644 --- a/spec/frontend/notes/components/discussion_resolve_button_spec.js +++ b/spec/frontend/notes/components/discussion_resolve_button_spec.js @@ -1,5 +1,6 @@ import { GlButton } from '@gitlab/ui'; import { shallowMount } from '@vue/test-utils'; +import { nextTick } from 'vue'; import resolveDiscussionButton from '~/notes/components/discussion_resolve_button.vue'; const buttonTitle = 'Resolve discussion'; @@ -26,15 +27,14 @@ describe('resolveDiscussionButton', () => { wrapper.destroy(); }); - it('should emit a onClick event on button click', () => { + it('should emit a onClick event on button click', async () => { const button = wrapper.find(GlButton); button.vm.$emit('click'); - return wrapper.vm.$nextTick().then(() => { - expect(wrapper.emitted()).toEqual({ - onClick: [[]], - }); + await nextTick(); + expect(wrapper.emitted()).toEqual({ + onClick: [[]], }); }); @@ -57,7 +57,7 @@ describe('resolveDiscussionButton', () => { expect(button.props('loading')).toEqual(true); }); - it('should only show a loading spinner while resolving', () => { + it('should only show a loading spinner while resolving', async () => { factory({ propsData: { isResolving: false, @@ -67,8 +67,7 @@ describe('resolveDiscussionButton', () => { const button = wrapper.find(GlButton); - wrapper.vm.$nextTick(() => { - expect(button.props('loading')).toEqual(false); - }); + await nextTick(); + expect(button.props('loading')).toEqual(false); }); }); 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 4348445f7ca..5bc6282db03 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,17 +1,14 @@ import { GlButton } from '@gitlab/ui'; -import { shallowMount, createLocalVue } from '@vue/test-utils'; +import { shallowMount } from '@vue/test-utils'; import { TEST_HOST } from 'spec/test_constants'; import ResolveWithIssueButton from '~/notes/components/discussion_resolve_with_issue_button.vue'; -const localVue = createLocalVue(); - describe('ResolveWithIssueButton', () => { let wrapper; const url = `${TEST_HOST}/hello-world/`; beforeEach(() => { wrapper = shallowMount(ResolveWithIssueButton, { - localVue, propsData: { url, }, diff --git a/spec/frontend/notes/components/note_actions_spec.js b/spec/frontend/notes/components/note_actions_spec.js index ecce854b00a..780f24b3aa8 100644 --- a/spec/frontend/notes/components/note_actions_spec.js +++ b/spec/frontend/notes/components/note_actions_spec.js @@ -1,6 +1,6 @@ -import { mount, createLocalVue, createWrapper } from '@vue/test-utils'; +import { mount, createWrapper } from '@vue/test-utils'; import AxiosMockAdapter from 'axios-mock-adapter'; -import Vue from 'vue'; +import { nextTick } from 'vue'; import { TEST_HOST } from 'spec/test_constants'; import axios from '~/lib/utils/axios_utils'; import { BV_HIDE_TOOLTIP } from '~/lib/utils/constants'; @@ -20,11 +20,9 @@ describe('noteActions', () => { const findUserAccessRoleBadgeText = (idx) => findUserAccessRoleBadge(idx).text().trim(); const mountNoteActions = (propsData, computed) => { - const localVue = createLocalVue(); - return mount(localVue.extend(noteActions), { + return mount(noteActions, { store, propsData, - localVue, computed, }); }; @@ -78,15 +76,14 @@ describe('noteActions', () => { expect(findUserAccessRoleBadgeText(1)).toBe(props.accessLevel); }); - it('should render contributor badge', () => { + it('should render contributor badge', async () => { wrapper.setProps({ accessLevel: null, isContributor: true, }); - return wrapper.vm.$nextTick().then(() => { - expect(findUserAccessRoleBadgeText(1)).toBe('Contributor'); - }); + await nextTick(); + expect(findUserAccessRoleBadgeText(1)).toBe('Contributor'); }); it('should render emoji link', () => { @@ -107,7 +104,7 @@ describe('noteActions', () => { expect(wrapper.find('.js-btn-copy-note-link').exists()).toBe(true); }); - it('should not show copy link action when `noteUrl` prop is empty', (done) => { + it('should not show copy link action when `noteUrl` prop is empty', async () => { wrapper.setProps({ ...props, author: { @@ -121,30 +118,23 @@ describe('noteActions', () => { noteUrl: '', }); - Vue.nextTick() - .then(() => { - expect(wrapper.find('.js-btn-copy-note-link').exists()).toBe(false); - }) - .then(done) - .catch(done.fail); + await nextTick(); + expect(wrapper.find('.js-btn-copy-note-link').exists()).toBe(false); }); it('should be possible to delete comment', () => { expect(wrapper.find('.js-note-delete').exists()).toBe(true); }); - it('closes tooltip when dropdown opens', (done) => { + it('closes tooltip when dropdown opens', async () => { wrapper.find('.more-actions-toggle').trigger('click'); const rootWrapper = createWrapper(wrapper.vm.$root); - Vue.nextTick() - .then(() => { - const emitted = Object.keys(rootWrapper.emitted()); - - expect(emitted).toEqual([BV_HIDE_TOOLTIP]); - done(); - }) - .catch(done.fail); + + await nextTick(); + const emitted = Object.keys(rootWrapper.emitted()); + + expect(emitted).toEqual([BV_HIDE_TOOLTIP]); }); it('should not be possible to assign or unassign the comment author in a merge request', () => { diff --git a/spec/frontend/notes/components/note_body_spec.js b/spec/frontend/notes/components/note_body_spec.js index 4e345c9ac8d..63f3cd865d5 100644 --- a/spec/frontend/notes/components/note_body_spec.js +++ b/spec/frontend/notes/components/note_body_spec.js @@ -1,5 +1,5 @@ import { shallowMount } from '@vue/test-utils'; -import Vue from 'vue'; +import Vue, { nextTick } from 'vue'; import Vuex from 'vuex'; import { suggestionCommitMessage } from '~/diffs/store/getters'; @@ -46,9 +46,9 @@ describe('issue_note_body component', () => { }); describe('isEditing', () => { - beforeEach((done) => { + beforeEach(async () => { vm.isEditing = true; - Vue.nextTick(done); + await nextTick(); }); it('renders edit form', () => { diff --git a/spec/frontend/notes/components/note_form_spec.js b/spec/frontend/notes/components/note_form_spec.js index d3b5ab02f24..3e80b24f128 100644 --- a/spec/frontend/notes/components/note_form_spec.js +++ b/spec/frontend/notes/components/note_form_spec.js @@ -45,6 +45,8 @@ describe('issue_note_form component', () => { noteBody: 'Magni suscipit eius consectetur enim et ex et commodi.', noteId: '545', }; + + gon.features = { markdownContinueLists: true }; }); afterEach(() => { diff --git a/spec/frontend/notes/components/note_header_spec.js b/spec/frontend/notes/components/note_header_spec.js index 774d5aaa7d3..8d82cf3d2c7 100644 --- a/spec/frontend/notes/components/note_header_spec.js +++ b/spec/frontend/notes/components/note_header_spec.js @@ -1,13 +1,12 @@ import { GlSprintf } from '@gitlab/ui'; -import { shallowMount, createLocalVue } from '@vue/test-utils'; -import { nextTick } from 'vue'; +import { shallowMount } from '@vue/test-utils'; +import Vue, { nextTick } from 'vue'; import Vuex from 'vuex'; import NoteHeader from '~/notes/components/note_header.vue'; import { AVAILABILITY_STATUS } from '~/set_status_modal/utils'; import UserNameWithStatus from '~/sidebar/components/assignees/user_name_with_status.vue'; -const localVue = createLocalVue(); -localVue.use(Vuex); +Vue.use(Vuex); const actions = { setTargetNoteHash: jest.fn(), @@ -42,7 +41,6 @@ describe('NoteHeader component', () => { const createComponent = (props) => { wrapper = shallowMount(NoteHeader, { - localVue, store: new Vuex.Store({ actions, }), diff --git a/spec/frontend/notes/components/noteable_note_spec.js b/spec/frontend/notes/components/noteable_note_spec.js index 038aff3be04..c7115a5911b 100644 --- a/spec/frontend/notes/components/noteable_note_spec.js +++ b/spec/frontend/notes/components/noteable_note_spec.js @@ -1,5 +1,5 @@ import { mount } from '@vue/test-utils'; -import Vue from 'vue'; +import Vue, { nextTick } from 'vue'; import Vuex from 'vuex'; import waitForPromises from 'helpers/wait_for_promises'; @@ -107,11 +107,11 @@ describe('issue_note', () => { line, }); - await wrapper.vm.$nextTick(); + await nextTick(); expect(findMultilineComment().text()).toBe('Comment on lines 1 to 2'); }); - it('should only render if it has everything it needs', () => { + it('should only render if it has everything it needs', async () => { const position = { line_range: { start: { @@ -140,12 +140,11 @@ describe('issue_note', () => { line, }); - return wrapper.vm.$nextTick().then(() => { - expect(findMultilineComment().exists()).toBe(false); - }); + await nextTick(); + expect(findMultilineComment().exists()).toBe(false); }); - it('should not render if has single line comment', () => { + it('should not render if has single line comment', async () => { const position = { line_range: { start: { @@ -174,9 +173,8 @@ describe('issue_note', () => { line, }); - return wrapper.vm.$nextTick().then(() => { - expect(findMultilineComment().exists()).toBe(false); - }); + await nextTick(); + expect(findMultilineComment().exists()).toBe(false); }); it('should not render if `line_range` is unavailable', () => { @@ -204,7 +202,7 @@ describe('issue_note', () => { line, }); - await wrapper.vm.$nextTick(); + await nextTick(); expect(wrapper.findComponent(UserAvatarLink).props('imgSize')).toBe(24); }); @@ -318,13 +316,13 @@ describe('issue_note', () => { callback: () => {}, }); - await wrapper.vm.$nextTick(); + await nextTick(); let noteBodyProps = noteBody.props(); expect(noteBodyProps.note.note_html).toBe(`<p>${updatedText}</p>\n`); noteBody.vm.$emit('cancelForm', {}); - await wrapper.vm.$nextTick(); + await nextTick(); noteBodyProps = noteBody.props(); diff --git a/spec/frontend/notes/components/notes_app_spec.js b/spec/frontend/notes/components/notes_app_spec.js index 84d94857fe5..bf36d6cb7a2 100644 --- a/spec/frontend/notes/components/notes_app_spec.js +++ b/spec/frontend/notes/components/notes_app_spec.js @@ -1,7 +1,7 @@ import { mount, shallowMount } from '@vue/test-utils'; import AxiosMockAdapter from 'axios-mock-adapter'; import $ from 'jquery'; -import Vue from 'vue'; +import { nextTick } from 'vue'; import setWindowLocation from 'helpers/set_window_location_helper'; import { setTestTimeout } from 'helpers/timeout'; import waitForPromises from 'helpers/wait_for_promises'; @@ -294,24 +294,22 @@ describe('note_app', () => { return waitForDiscussionsRequest(); }); - it('should render markdown docs url', () => { + it('should render markdown docs url', async () => { wrapper.find('.js-note-edit').trigger('click'); const { markdownDocsPath } = mockData.notesDataMock; - return Vue.nextTick().then(() => { - expect(wrapper.find(`.edit-note a[href="${markdownDocsPath}"]`).text().trim()).toEqual( - 'Markdown is supported', - ); - }); + await nextTick(); + expect(wrapper.find(`.edit-note a[href="${markdownDocsPath}"]`).text().trim()).toEqual( + 'Markdown is supported', + ); }); - it('should not render quick actions docs url', () => { + it('should not render quick actions docs url', async () => { wrapper.find('.js-note-edit').trigger('click'); const { quickActionsDocsPath } = mockData.notesDataMock; - return wrapper.vm.$nextTick().then(() => { - expect(wrapper.find(`.edit-note a[href="${quickActionsDocsPath}"]`).exists()).toBe(false); - }); + await nextTick(); + expect(wrapper.find(`.edit-note a[href="${quickActionsDocsPath}"]`).exists()).toBe(false); }); }); diff --git a/spec/frontend/notes/components/sort_discussion_spec.js b/spec/frontend/notes/components/sort_discussion_spec.js index 60f03a0f5b5..a279dfd1ef3 100644 --- a/spec/frontend/notes/components/sort_discussion_spec.js +++ b/spec/frontend/notes/components/sort_discussion_spec.js @@ -1,4 +1,5 @@ -import { shallowMount, createLocalVue } from '@vue/test-utils'; +import { shallowMount } from '@vue/test-utils'; +import Vue from 'vue'; import Vuex from 'vuex'; import SortDiscussion from '~/notes/components/sort_discussion.vue'; import { ASC, DESC } from '~/notes/constants'; @@ -6,8 +7,7 @@ import createStore from '~/notes/stores'; import Tracking from '~/tracking'; import LocalStorageSync from '~/vue_shared/components/local_storage_sync.vue'; -const localVue = createLocalVue(); -localVue.use(Vuex); +Vue.use(Vuex); describe('Sort Discussion component', () => { let wrapper; @@ -17,7 +17,6 @@ describe('Sort Discussion component', () => { jest.spyOn(store, 'dispatch').mockImplementation(); wrapper = shallowMount(SortDiscussion, { - localVue, store, }); }; diff --git a/spec/frontend/notes/components/timeline_toggle_spec.js b/spec/frontend/notes/components/timeline_toggle_spec.js index 73fb2079e31..84fa3008835 100644 --- a/spec/frontend/notes/components/timeline_toggle_spec.js +++ b/spec/frontend/notes/components/timeline_toggle_spec.js @@ -1,5 +1,6 @@ import { GlButton } from '@gitlab/ui'; -import { shallowMount, createLocalVue } from '@vue/test-utils'; +import { shallowMount } from '@vue/test-utils'; +import Vue, { nextTick } from 'vue'; import Vuex from 'vuex'; import TimelineToggle, { timelineEnabledTooltip, @@ -10,8 +11,7 @@ import createStore from '~/notes/stores'; import { trackToggleTimelineView } from '~/notes/utils'; import Tracking from '~/tracking'; -const localVue = createLocalVue(); -localVue.use(Vuex); +Vue.use(Vuex); describe('Timeline toggle', () => { let wrapper; @@ -23,7 +23,6 @@ describe('Timeline toggle', () => { jest.spyOn(Tracking, 'event').mockImplementation(); wrapper = shallowMount(TimelineToggle, { - localVue, store, }); }; @@ -65,7 +64,7 @@ describe('Timeline toggle', () => { it('should set correct UI state', async () => { store.state.isTimelineEnabled = true; findGlButton().vm.$emit('click', mockEvent); - await wrapper.vm.$nextTick(); + await nextTick(); expect(findGlButton().attributes('title')).toBe(timelineEnabledTooltip); expect(findGlButton().attributes('selected')).toBe('true'); expect(mockEvent.currentTarget.blur).toHaveBeenCalled(); @@ -73,7 +72,7 @@ describe('Timeline toggle', () => { it('should track Snowplow event', async () => { store.state.isTimelineEnabled = true; - await wrapper.vm.$nextTick(); + await nextTick(); findGlButton().trigger('click'); @@ -98,7 +97,7 @@ describe('Timeline toggle', () => { it('should set correct UI state', async () => { store.state.isTimelineEnabled = false; findGlButton().vm.$emit('click', mockEvent); - await wrapper.vm.$nextTick(); + await nextTick(); expect(findGlButton().attributes('title')).toBe(timelineDisabledTooltip); expect(findGlButton().attributes('selected')).toBe(undefined); expect(mockEvent.currentTarget.blur).toHaveBeenCalled(); @@ -106,7 +105,7 @@ describe('Timeline toggle', () => { it('should track Snowplow event', async () => { store.state.isTimelineEnabled = false; - await wrapper.vm.$nextTick(); + await nextTick(); findGlButton().trigger('click'); diff --git a/spec/frontend/notes/deprecated_notes_spec.js b/spec/frontend/notes/deprecated_notes_spec.js index 34623f8aa13..7c52920da90 100644 --- a/spec/frontend/notes/deprecated_notes_spec.js +++ b/spec/frontend/notes/deprecated_notes_spec.js @@ -5,6 +5,7 @@ import $ from 'jquery'; import '~/behaviors/markdown/render_gfm'; import { createSpyObj } from 'helpers/jest_helpers'; import { TEST_HOST } from 'helpers/test_constants'; +import waitForPromises from 'helpers/wait_for_promises'; import { setTestTimeoutOnce } from 'helpers/timeout'; import axios from '~/lib/utils/axios_utils'; import * as urlUtility from '~/lib/utils/url_utility'; @@ -549,15 +550,14 @@ describe.skip('Old Notes (~/deprecated_notes.js)', () => { expect($notesContainer.find('.note.being-posted').length).toBeGreaterThan(0); }); - it('should remove placeholder note when new comment is done posting', (done) => { + it('should remove placeholder note when new comment is done posting', async () => { mockNotesPost(); $('.js-comment-button').click(); - setImmediate(() => { - expect($notesContainer.find('.note.being-posted').length).toEqual(0); - done(); - }); + await waitForPromises(); + + expect($notesContainer.find('.note.being-posted').length).toEqual(0); }); describe('postComment', () => { @@ -584,40 +584,37 @@ describe.skip('Old Notes (~/deprecated_notes.js)', () => { }); }); - it('should show actual note element when new comment is done posting', (done) => { + it('should show actual note element when new comment is done posting', async () => { mockNotesPost(); $('.js-comment-button').click(); - setImmediate(() => { - expect($notesContainer.find(`#note_${note.id}`).length).toBeGreaterThan(0); - done(); - }); + await waitForPromises(); + + expect($notesContainer.find(`#note_${note.id}`).length).toBeGreaterThan(0); }); - it('should reset Form when new comment is done posting', (done) => { + it('should reset Form when new comment is done posting', async () => { mockNotesPost(); $('.js-comment-button').click(); - setImmediate(() => { - expect($form.find('textarea.js-note-text').val()).toEqual(''); - done(); - }); + await waitForPromises(); + + expect($form.find('textarea.js-note-text').val()).toEqual(''); }); - it('should show flash error message when new comment failed to be posted', (done) => { + it('should show flash error message when new comment failed to be posted', async () => { mockNotesPostError(); jest.spyOn(notes, 'addFlash'); $('.js-comment-button').click(); - setImmediate(() => { - expect(notes.addFlash).toHaveBeenCalled(); - // JSDom doesn't support the :visible selector yet - expect(notes.flashContainer.style.display).not.toBe('none'); - done(); - }); + await waitForPromises(); + + expect(notes.addFlash).toHaveBeenCalled(); + // JSDom doesn't support the :visible selector yet + expect(notes.flashContainer.style.display).not.toBe('none'); }); }); @@ -657,16 +654,15 @@ describe.skip('Old Notes (~/deprecated_notes.js)', () => { $form.find('textarea.js-note-text').val(sampleComment); }); - it('should remove quick action placeholder when comment with quick actions is done posting', (done) => { + it('should remove quick action placeholder when comment with quick actions is done posting', async () => { jest.spyOn(gl.awardsHandler, 'addAwardToEmojiBar'); $('.js-comment-button').click(); expect($notesContainer.find('.note.being-posted').length).toEqual(1); // Placeholder shown - setImmediate(() => { - expect($notesContainer.find('.note.being-posted').length).toEqual(0); // Placeholder removed - done(); - }); + await waitForPromises(); + + expect($notesContainer.find('.note.being-posted').length).toEqual(0); // Placeholder removed }); }); @@ -692,16 +688,15 @@ describe.skip('Old Notes (~/deprecated_notes.js)', () => { $form.find('textarea.js-note-text').val(sampleComment); }); - it('should show message placeholder including lines starting with slash', (done) => { + it('should show message placeholder including lines starting with slash', async () => { $('.js-comment-button').click(); expect($notesContainer.find('.note.being-posted').length).toEqual(1); // Placeholder shown expect($notesContainer.find('.note-body p').text()).toEqual(sampleComment); // No quick action processing - setImmediate(() => { - expect($notesContainer.find('.note.being-posted').length).toEqual(0); // Placeholder removed - done(); - }); + await waitForPromises(); + + expect($notesContainer.find('.note.being-posted').length).toEqual(0); // Placeholder removed }); }); @@ -730,23 +725,21 @@ describe.skip('Old Notes (~/deprecated_notes.js)', () => { $form.find('textarea.js-note-text').html(sampleComment); }); - it('should not render a script tag', (done) => { + it('should not render a script tag', async () => { $('.js-comment-button').click(); - setImmediate(() => { - const $noteEl = $notesContainer.find(`#note_${note.id}`); - $noteEl.find('.js-note-edit').click(); - $noteEl.find('textarea.js-note-text').html(updatedComment); - $noteEl.find('.js-comment-save-button').click(); + await waitForPromises(); - const $updatedNoteEl = $notesContainer - .find(`#note_${note.id}`) - .find('.js-task-list-container'); + const $noteEl = $notesContainer.find(`#note_${note.id}`); + $noteEl.find('.js-note-edit').click(); + $noteEl.find('textarea.js-note-text').html(updatedComment); + $noteEl.find('.js-comment-save-button').click(); - expect($updatedNoteEl.find('.note-text').text().trim()).toEqual(''); + const $updatedNoteEl = $notesContainer + .find(`#note_${note.id}`) + .find('.js-task-list-container'); - done(); - }); + expect($updatedNoteEl.find('.note-text').text().trim()).toEqual(''); }); }); diff --git a/spec/frontend/notes/mixins/discussion_navigation_spec.js b/spec/frontend/notes/mixins/discussion_navigation_spec.js index 26a072b82f8..aba80789a01 100644 --- a/spec/frontend/notes/mixins/discussion_navigation_spec.js +++ b/spec/frontend/notes/mixins/discussion_navigation_spec.js @@ -1,5 +1,5 @@ -import { shallowMount, createLocalVue } from '@vue/test-utils'; -import { nextTick } from 'vue'; +import { shallowMount } from '@vue/test-utils'; +import Vue, { nextTick } from 'vue'; import Vuex from 'vuex'; import { setHTMLFixture } from 'helpers/fixtures'; import createEventHub from '~/helpers/event_hub_factory'; @@ -27,8 +27,7 @@ const createComponent = () => ({ }); describe('Discussion navigation mixin', () => { - const localVue = createLocalVue(); - localVue.use(Vuex); + Vue.use(Vuex); let wrapper; let store; @@ -65,7 +64,7 @@ describe('Discussion navigation mixin', () => { }); store.state.notes.discussions = createDiscussions(); - wrapper = shallowMount(createComponent(), { store, localVue }); + wrapper = shallowMount(createComponent(), { store }); }); afterEach(() => { @@ -94,14 +93,13 @@ describe('Discussion navigation mixin', () => { expect(store.dispatch).toHaveBeenCalledWith('setCurrentDiscussionId', null); }); - it('triggers the jumpToNextDiscussion action when the previous store action succeeds', () => { + it('triggers the jumpToNextDiscussion action when the previous store action succeeds', async () => { store.dispatch.mockResolvedValue(); vm.jumpToFirstUnresolvedDiscussion(); - return vm.$nextTick().then(() => { - expect(vm.jumpToNextDiscussion).toHaveBeenCalled(); - }); + await nextTick(); + expect(vm.jumpToNextDiscussion).toHaveBeenCalled(); }); }); @@ -127,11 +125,11 @@ describe('Discussion navigation mixin', () => { }); describe('on `show` active tab', () => { - beforeEach(() => { + beforeEach(async () => { window.mrTabs.currentAction = 'show'; wrapper.vm[fn](...args); - return wrapper.vm.$nextTick(); + await nextTick(); }); it('sets current discussion', () => { @@ -145,17 +143,17 @@ describe('Discussion navigation mixin', () => { it('scrolls to element', () => { expect(utils.scrollToElement).toHaveBeenCalledWith( findDiscussion('div.discussion', expected), - { behavior: 'smooth' }, + { behavior: 'auto' }, ); }); }); describe('on `diffs` active tab', () => { - beforeEach(() => { + beforeEach(async () => { window.mrTabs.currentAction = 'diffs'; wrapper.vm[fn](...args); - return wrapper.vm.$nextTick(); + await nextTick(); }); it('sets current discussion', () => { @@ -173,17 +171,17 @@ describe('Discussion navigation mixin', () => { expect(utils.scrollToElementWithContext).toHaveBeenCalledWith( findDiscussion('ul.notes', expected), - { behavior: 'smooth' }, + { behavior: 'auto' }, ); }); }); describe('on `other` active tab', () => { - beforeEach(() => { + beforeEach(async () => { window.mrTabs.currentAction = 'other'; wrapper.vm[fn](...args); - return wrapper.vm.$nextTick(); + await nextTick(); }); it('sets current discussion', () => { @@ -214,21 +212,15 @@ describe('Discussion navigation mixin', () => { it('scrolls to discussion', () => { expect(utils.scrollToElement).toHaveBeenCalledWith( findDiscussion('div.discussion', expected), - { behavior: 'smooth' }, + { behavior: 'auto' }, ); }); }); }); }); - describe.each` - diffsVirtualScrolling - ${false} - ${true} - `('virtual scrolling feature is $diffsVirtualScrolling', ({ diffsVirtualScrolling }) => { + describe('virtual scrolling feature', () => { beforeEach(() => { - window.gon = { features: { diffsVirtualScrolling } }; - jest.spyOn(store, 'dispatch'); store.state.notes.currentDiscussionId = 'a'; @@ -240,22 +232,22 @@ describe('Discussion navigation mixin', () => { window.location.hash = ''; }); - it('resets location hash if diffsVirtualScrolling flag is true', async () => { + it('resets location hash', async () => { wrapper.vm.jumpToNextDiscussion(); await nextTick(); - expect(window.location.hash).toBe(diffsVirtualScrolling ? '' : '#test'); + expect(window.location.hash).toBe(''); }); it.each` - tabValue | hashValue - ${'diffs'} | ${false} - ${'show'} | ${!diffsVirtualScrolling} - ${'other'} | ${!diffsVirtualScrolling} + tabValue + ${'diffs'} + ${'show'} + ${'other'} `( 'calls scrollToFile with setHash as $hashValue when the tab is $tabValue', - async ({ hashValue, tabValue }) => { + async ({ tabValue }) => { window.mrTabs.currentAction = tabValue; wrapper.vm.jumpToNextDiscussion(); @@ -264,7 +256,6 @@ describe('Discussion navigation mixin', () => { expect(store.dispatch).toHaveBeenCalledWith('diffs/scrollToFile', { path: 'test.js', - setHash: hashValue, }); }, ); |