From 6438df3a1e0fb944485cebf07976160184697d72 Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Wed, 20 Jan 2021 13:34:23 -0600 Subject: Add latest changes from gitlab-org/gitlab@13-8-stable-ee --- .../discussion_jump_to_next_button_spec.js.snap | 21 ---- .../notes/components/comment_field_layout_spec.js | 137 +++++++++++++++++++++ .../frontend/notes/components/comment_form_spec.js | 15 +-- .../components/diff_discussion_header_spec.js | 10 +- .../notes/components/discussion_actions_spec.js | 33 +---- .../notes/components/discussion_counter_spec.js | 2 +- .../components/discussion_filter_note_spec.js | 10 +- .../notes/components/discussion_filter_spec.js | 26 ++-- .../discussion_jump_to_next_button_spec.js | 43 ------- .../notes/components/discussion_notes_spec.js | 5 +- .../components/discussion_resolve_button_spec.js | 2 +- .../components/email_participants_warning_spec.js | 70 +++++++++++ .../components/multiline_comment_form_spec.js | 89 +++++++++++++ .../components/multiline_comment_utils_spec.js | 4 +- .../frontend/notes/components/note_actions_spec.js | 28 +---- .../notes/components/note_attachment_spec.js | 2 +- .../notes/components/note_awards_list_spec.js | 8 +- spec/frontend/notes/components/note_body_spec.js | 2 +- spec/frontend/notes/components/note_form_spec.js | 86 ++++++------- spec/frontend/notes/components/note_header_spec.js | 4 +- .../notes/components/noteable_discussion_spec.js | 80 ++++++------ .../notes/components/noteable_note_spec.js | 4 +- spec/frontend/notes/components/notes_app_spec.js | 44 +++---- .../notes/components/toggle_replies_widget_spec.js | 2 +- 24 files changed, 430 insertions(+), 297 deletions(-) delete mode 100644 spec/frontend/notes/components/__snapshots__/discussion_jump_to_next_button_spec.js.snap create mode 100644 spec/frontend/notes/components/comment_field_layout_spec.js delete mode 100644 spec/frontend/notes/components/discussion_jump_to_next_button_spec.js create mode 100644 spec/frontend/notes/components/email_participants_warning_spec.js create mode 100644 spec/frontend/notes/components/multiline_comment_form_spec.js (limited to 'spec/frontend/notes/components') diff --git a/spec/frontend/notes/components/__snapshots__/discussion_jump_to_next_button_spec.js.snap b/spec/frontend/notes/components/__snapshots__/discussion_jump_to_next_button_spec.js.snap deleted file mode 100644 index 13af29821d8..00000000000 --- a/spec/frontend/notes/components/__snapshots__/discussion_jump_to_next_button_spec.js.snap +++ /dev/null @@ -1,21 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`JumpToNextDiscussionButton matches the snapshot 1`] = ` -
- -
-`; diff --git a/spec/frontend/notes/components/comment_field_layout_spec.js b/spec/frontend/notes/components/comment_field_layout_spec.js new file mode 100644 index 00000000000..4d9b4ea8c6f --- /dev/null +++ b/spec/frontend/notes/components/comment_field_layout_spec.js @@ -0,0 +1,137 @@ +import { shallowMount } from '@vue/test-utils'; +import { extendedWrapper } from 'helpers/vue_test_utils_helper'; +import CommentFieldLayout from '~/notes/components/comment_field_layout.vue'; +import EmailParticipantsWarning from '~/notes/components/email_participants_warning.vue'; +import NoteableWarning from '~/vue_shared/components/notes/noteable_warning.vue'; + +describe('Comment Field Layout Component', () => { + let wrapper; + + afterEach(() => { + wrapper.destroy(); + wrapper = null; + }); + + const LOCKED_DISCUSSION_DOCS_PATH = 'docs/locked/path'; + const CONFIDENTIAL_ISSUES_DOCS_PATH = 'docs/confidential/path'; + + const noteableDataMock = { + confidential: false, + discussion_locked: false, + locked_discussion_docs_path: LOCKED_DISCUSSION_DOCS_PATH, + confidential_issues_docs_path: CONFIDENTIAL_ISSUES_DOCS_PATH, + }; + + const findIssuableNoteWarning = () => wrapper.find(NoteableWarning); + const findEmailParticipantsWarning = () => wrapper.find(EmailParticipantsWarning); + const findErrorAlert = () => wrapper.findByTestId('comment-field-alert-container'); + + const createWrapper = (props = {}, slots = {}) => { + wrapper = extendedWrapper( + shallowMount(CommentFieldLayout, { + propsData: { + noteableData: noteableDataMock, + ...props, + }, + slots, + }), + ); + }; + + describe('.error-alert', () => { + it('does not exist by default', () => { + createWrapper(); + + expect(findErrorAlert().exists()).toBe(false); + }); + + it('exists when withAlertContainer is true', () => { + createWrapper({ withAlertContainer: true }); + + expect(findErrorAlert().isVisible()).toBe(true); + }); + }); + + describe('issue is not confidential and not locked', () => { + it('does not show IssuableNoteWarning', () => { + createWrapper(); + + expect(findIssuableNoteWarning().exists()).toBe(false); + }); + }); + + describe('issue is confidential', () => { + beforeEach(() => { + createWrapper({ + noteableData: { ...noteableDataMock, confidential: true }, + }); + }); + + it('shows IssuableNoteWarning', () => { + expect(findIssuableNoteWarning().isVisible()).toBe(true); + }); + + it('sets IssuableNoteWarning props', () => { + expect(findIssuableNoteWarning().props()).toMatchObject({ + isLocked: false, + isConfidential: true, + lockedNoteableDocsPath: LOCKED_DISCUSSION_DOCS_PATH, + confidentialNoteableDocsPath: CONFIDENTIAL_ISSUES_DOCS_PATH, + }); + }); + }); + + describe('issue is locked', () => { + beforeEach(() => { + createWrapper({ + noteableData: { ...noteableDataMock, discussion_locked: true }, + }); + }); + + it('shows IssuableNoteWarning', () => { + expect(findIssuableNoteWarning().isVisible()).toBe(true); + }); + + it('sets IssuableNoteWarning props', () => { + expect(findIssuableNoteWarning().props()).toMatchObject({ + isConfidential: false, + isLocked: true, + lockedNoteableDocsPath: LOCKED_DISCUSSION_DOCS_PATH, + confidentialNoteableDocsPath: CONFIDENTIAL_ISSUES_DOCS_PATH, + }); + }); + }); + + describe('issue has no email participants', () => { + it('does not show EmailParticipantsWarning', () => { + createWrapper(); + + expect(findEmailParticipantsWarning().exists()).toBe(false); + }); + }); + + describe('issue has email participants', () => { + beforeEach(() => { + createWrapper({ + noteableData: { + ...noteableDataMock, + issue_email_participants: [ + { email: 'someone@gitlab.com' }, + { email: 'another@gitlab.com' }, + ], + }, + }); + }); + + it('shows EmailParticipantsWarning', () => { + expect(findEmailParticipantsWarning().isVisible()).toBe(true); + }); + + it('sets EmailParticipantsWarning props', () => { + expect(findEmailParticipantsWarning().props('emails')).toEqual([ + 'someone@gitlab.com', + 'another@gitlab.com', + ]); + }); + }); +}); diff --git a/spec/frontend/notes/components/comment_form_spec.js b/spec/frontend/notes/components/comment_form_spec.js index fca1beca999..002c4f206cb 100644 --- a/spec/frontend/notes/components/comment_form_spec.js +++ b/spec/frontend/notes/components/comment_form_spec.js @@ -181,7 +181,7 @@ describe('issue_comment_form component', () => { describe('edit mode', () => { beforeEach(() => { - mountComponent(); + mountComponent({ mountFunction: mount }); }); it('should enter edit mode when arrow up is pressed', () => { @@ -200,7 +200,7 @@ describe('issue_comment_form component', () => { describe('event enter', () => { beforeEach(() => { - mountComponent(); + mountComponent({ mountFunction: mount }); }); it('should save note when cmd+enter is pressed', () => { @@ -368,17 +368,6 @@ describe('issue_comment_form component', () => { }); }); }); - - describe('issue is confidential', () => { - it('shows information warning', () => { - mountComponent({ - noteableData: { ...noteableDataMock, confidential: true }, - mountFunction: mount, - }); - - expect(wrapper.find('[data-testid="confidential-warning"]').exists()).toBe(true); - }); - }); }); describe('user is not logged in', () => { diff --git a/spec/frontend/notes/components/diff_discussion_header_spec.js b/spec/frontend/notes/components/diff_discussion_header_spec.js index 9162bee2078..3940439a32b 100644 --- a/spec/frontend/notes/components/diff_discussion_header_spec.js +++ b/spec/frontend/notes/components/diff_discussion_header_spec.js @@ -45,7 +45,7 @@ describe('diff_discussion_header component', () => { const truncatedCommitId = commitId.substr(0, 8); let commitElement; - beforeEach(done => { + beforeEach((done) => { store.state.diffs = { projectPath: 'something', }; @@ -72,7 +72,7 @@ describe('diff_discussion_header component', () => { }); 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', (done) => { Object.assign(wrapper.vm.discussion, { for_commit: false, commit_id: null, @@ -85,7 +85,7 @@ describe('diff_discussion_header component', () => { }); }); - it('should show thread on older version text', done => { + it('should show thread on older version text', (done) => { Object.assign(wrapper.vm.discussion, { for_commit: false, commit_id: null, @@ -109,7 +109,7 @@ 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', (done) => { wrapper.vm.discussion.for_commit = false; wrapper.vm.$nextTick(() => { @@ -121,7 +121,7 @@ describe('diff_discussion_header component', () => { }); }); - it('should display outdated change on commit header', done => { + it('should display outdated change on commit header', (done) => { wrapper.vm.discussion.for_commit = false; wrapper.vm.discussion.active = false; diff --git a/spec/frontend/notes/components/discussion_actions_spec.js b/spec/frontend/notes/components/discussion_actions_spec.js index b26eb00bfdc..48e569720e9 100644 --- a/spec/frontend/notes/components/discussion_actions_spec.js +++ b/spec/frontend/notes/components/discussion_actions_spec.js @@ -4,7 +4,6 @@ import DiscussionActions from '~/notes/components/discussion_actions.vue'; import ReplyPlaceholder from '~/notes/components/discussion_reply_placeholder.vue'; import ResolveDiscussionButton from '~/notes/components/discussion_resolve_button.vue'; import ResolveWithIssueButton from '~/notes/components/discussion_resolve_with_issue_button.vue'; -import JumpToNextDiscussionButton from '~/notes/components/discussion_jump_to_next_button.vue'; import createStore from '~/notes/stores'; // NOTE: clone mock_data so that it is not accidentally mutated @@ -21,7 +20,7 @@ const createUnallowedNote = () => describe('DiscussionActions', () => { let wrapper; - const createComponentFactory = (shallow = true) => (props, options) => { + const createComponentFactory = (shallow = true) => (props) => { const store = createStore(); const mountFn = shallow ? shallowMount : mount; @@ -35,11 +34,6 @@ describe('DiscussionActions', () => { shouldShowJumpToNextDiscussion: true, ...props, }, - provide: { - glFeatures: { - hideJumpToNextUnresolvedInThreads: options?.hideJumpToNextUnresolvedInThreads, - }, - }, }); }; @@ -55,7 +49,6 @@ describe('DiscussionActions', () => { expect(wrapper.find(ReplyPlaceholder).exists()).toBe(true); expect(wrapper.find(ResolveDiscussionButton).exists()).toBe(true); expect(wrapper.find(ResolveWithIssueButton).exists()).toBe(true); - expect(wrapper.find(JumpToNextDiscussionButton).exists()).toBe(true); }); it('only renders reply placholder if disccusion is not resolvable', () => { @@ -66,7 +59,6 @@ describe('DiscussionActions', () => { expect(wrapper.find(ReplyPlaceholder).exists()).toBe(true); expect(wrapper.find(ResolveDiscussionButton).exists()).toBe(false); expect(wrapper.find(ResolveWithIssueButton).exists()).toBe(false); - expect(wrapper.find(JumpToNextDiscussionButton).exists()).toBe(false); }); it('does not render resolve with issue button if resolveWithIssuePath is falsy', () => { @@ -75,12 +67,6 @@ describe('DiscussionActions', () => { expect(wrapper.find(ResolveWithIssueButton).exists()).toBe(false); }); - it('does not render jump to next discussion button if shouldShowJumpToNextDiscussion is false', () => { - createComponent({ shouldShowJumpToNextDiscussion: false }); - - expect(wrapper.find(JumpToNextDiscussionButton).exists()).toBe(false); - }); - describe.each` desc | notes | shouldRender ${'with no notes'} | ${[]} | ${true} @@ -101,13 +87,6 @@ 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); @@ -117,19 +96,13 @@ describe('DiscussionActions', () => { it('emits showReplyForm event when clicking on reply placeholder', () => { jest.spyOn(wrapper.vm, '$emit'); - wrapper - .find(ReplyPlaceholder) - .find('button') - .trigger('click'); + wrapper.find(ReplyPlaceholder).find('button').trigger('click'); expect(wrapper.vm.$emit).toHaveBeenCalledWith('showReplyForm'); }); it('emits resolve event when clicking on resolve button', () => { jest.spyOn(wrapper.vm, '$emit'); - wrapper - .find(ResolveDiscussionButton) - .find('button') - .trigger('click'); + wrapper.find(ResolveDiscussionButton).find('button').trigger('click'); expect(wrapper.vm.$emit).toHaveBeenCalledWith('resolve'); }); }); diff --git a/spec/frontend/notes/components/discussion_counter_spec.js b/spec/frontend/notes/components/discussion_counter_spec.js index d82590c7e9e..ebf7d52f38b 100644 --- a/spec/frontend/notes/components/discussion_counter_spec.js +++ b/spec/frontend/notes/components/discussion_counter_spec.js @@ -95,7 +95,7 @@ describe('DiscussionCounter component', () => { describe('toggle all threads button', () => { let toggleAllButton; - const updateStoreWithExpanded = expanded => { + const updateStoreWithExpanded = (expanded) => { const discussion = { ...discussionMock, expanded }; store.commit(types.SET_INITIAL_DISCUSSIONS, [discussion]); store.dispatch('updateResolvableDiscussionsCounts'); diff --git a/spec/frontend/notes/components/discussion_filter_note_spec.js b/spec/frontend/notes/components/discussion_filter_note_spec.js index d35f8f7c28d..9ae3f08df77 100644 --- a/spec/frontend/notes/components/discussion_filter_note_spec.js +++ b/spec/frontend/notes/components/discussion_filter_note_spec.js @@ -31,20 +31,14 @@ describe('DiscussionFilterNote component', () => { it('emits `dropdownSelect` event with 0 parameter on clicking Show all activity button', () => { jest.spyOn(eventHub, '$emit').mockImplementation(() => {}); - wrapper - .findAll(GlButton) - .at(0) - .vm.$emit('click'); + wrapper.findAll(GlButton).at(0).vm.$emit('click'); expect(eventHub.$emit).toHaveBeenCalledWith('dropdownSelect', 0); }); it('emits `dropdownSelect` event with 1 parameter on clicking Show comments only button', () => { jest.spyOn(eventHub, '$emit').mockImplementation(() => {}); - wrapper - .findAll(GlButton) - .at(1) - .vm.$emit('click'); + wrapper.findAll(GlButton).at(1).vm.$emit('click'); expect(eventHub.$emit).toHaveBeenCalledWith('dropdownSelect', 1); }); diff --git a/spec/frontend/notes/components/discussion_filter_spec.js b/spec/frontend/notes/components/discussion_filter_spec.js index 9f3655c53b9..aeba8e8056c 100644 --- a/spec/frontend/notes/components/discussion_filter_spec.js +++ b/spec/frontend/notes/components/discussion_filter_spec.js @@ -1,7 +1,7 @@ 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 { TEST_HOST } from 'helpers/test_constants'; import createEventHub from '~/helpers/event_hub_factory'; import axios from '~/lib/utils/axios_utils'; @@ -25,7 +25,8 @@ describe('DiscussionFilter component', () => { const filterDiscussion = jest.fn(); - const findFilter = filterType => wrapper.find(`.dropdown-item[data-filter-type="${filterType}"]`); + const findFilter = (filterType) => + wrapper.find(`.dropdown-item[data-filter-type="${filterType}"]`); const mountComponent = () => { const discussions = [ @@ -82,12 +83,9 @@ describe('DiscussionFilter component', () => { }); it('renders the default selected item', () => { - expect( - wrapper - .find('#discussion-filter-dropdown .dropdown-item') - .text() - .trim(), - ).toBe(discussionFiltersMock[0].title); + expect(wrapper.find('#discussion-filter-dropdown .dropdown-item').text().trim()).toBe( + discussionFiltersMock[0].title, + ); }); it('updates to the selected item', () => { @@ -148,7 +146,7 @@ describe('DiscussionFilter component', () => { window.mrTabs = undefined; }); - it('only renders when discussion tab is active', done => { + it('only renders when discussion tab is active', (done) => { eventHub.$emit('MergeRequestTabChange', 'commit'); wrapper.vm.$nextTick(() => { @@ -163,7 +161,7 @@ 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', (done) => { window.location.hash = `note_${discussionMock.notes[0].id}`; wrapper.vm.currentValue = discussionFiltersMock[2].value; wrapper.vm.handleLocationHash(); @@ -174,7 +172,7 @@ describe('DiscussionFilter component', () => { }); }); - 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"', (done) => { window.location.hash = `note_${discussionMock.notes[0].id}`; wrapper.vm.handleLocationHash(); @@ -184,7 +182,7 @@ describe('DiscussionFilter component', () => { }); }); - it('only updates filter when the URL links to a note', done => { + it('only updates filter when the URL links to a note', (done) => { window.location.hash = `testing123`; wrapper.vm.handleLocationHash(); @@ -194,7 +192,7 @@ describe('DiscussionFilter component', () => { }); }); - it('fetches discussions when there is a hash', done => { + it('fetches discussions when there is a hash', (done) => { window.location.hash = `note_${discussionMock.notes[0].id}`; wrapper.vm.currentValue = discussionFiltersMock[2].value; jest.spyOn(wrapper.vm, 'selectFilter').mockImplementation(() => {}); @@ -206,7 +204,7 @@ describe('DiscussionFilter component', () => { }); }); - it('does not fetch discussions when there is no hash', done => { + it('does not fetch discussions when there is no hash', (done) => { window.location.hash = ''; jest.spyOn(wrapper.vm, 'selectFilter').mockImplementation(() => {}); wrapper.vm.handleLocationHash(); diff --git a/spec/frontend/notes/components/discussion_jump_to_next_button_spec.js b/spec/frontend/notes/components/discussion_jump_to_next_button_spec.js deleted file mode 100644 index 183966cf435..00000000000 --- a/spec/frontend/notes/components/discussion_jump_to_next_button_spec.js +++ /dev/null @@ -1,43 +0,0 @@ -import { shallowMount } from '@vue/test-utils'; -import JumpToNextDiscussionButton from '~/notes/components/discussion_jump_to_next_button.vue'; -import { mockTracking } from '../../helpers/tracking_helper'; - -describe('JumpToNextDiscussionButton', () => { - const fromDiscussionId = 'abc123'; - let wrapper; - let trackingSpy; - let jumpFn; - - beforeEach(() => { - jumpFn = jest.fn(); - wrapper = shallowMount(JumpToNextDiscussionButton, { - propsData: { fromDiscussionId }, - }); - wrapper.setMethods({ jumpToNextRelativeDiscussion: jumpFn }); - - trackingSpy = mockTracking('_category_', wrapper.element, jest.spyOn); - }); - - afterEach(() => { - wrapper.destroy(); - }); - - it('matches the snapshot', () => { - expect(wrapper.vm.$el).toMatchSnapshot(); - }); - - it('calls jumpToNextRelativeDiscussion when clicked', () => { - wrapper.find({ ref: 'button' }).trigger('click'); - - expect(jumpFn).toHaveBeenCalledWith(fromDiscussionId); - }); - - it('sends the correct tracking event when clicked', () => { - wrapper.find({ ref: 'button' }).trigger('click'); - - expect(trackingSpy).toHaveBeenCalledWith('_category_', 'click_button', { - label: 'mr_next_unresolved_thread', - property: 'click_next_unresolved_thread', - }); - }); -}); diff --git a/spec/frontend/notes/components/discussion_notes_spec.js b/spec/frontend/notes/components/discussion_notes_spec.js index 8cc98f978c2..e803dcb7b4a 100644 --- a/spec/frontend/notes/components/discussion_notes_spec.js +++ b/spec/frontend/notes/components/discussion_notes_spec.js @@ -122,12 +122,11 @@ describe('DiscussionNotes', () => { describe('events', () => { describe('with groupped notes and replies expanded', () => { - const findNoteAtIndex = index => { + const findNoteAtIndex = (index) => { const noteComponents = [NoteableNote, SystemNote, PlaceholderNote, PlaceholderSystemNote]; - const allowedNames = noteComponents.map(c => c.name); return wrapper .findAll('.notes *') - .filter(w => allowedNames.includes(w.name())) + .filter((w) => noteComponents.some((Component) => w.is(Component))) .at(index); }; diff --git a/spec/frontend/notes/components/discussion_resolve_button_spec.js b/spec/frontend/notes/components/discussion_resolve_button_spec.js index 41701e54dfa..5105e1013d3 100644 --- a/spec/frontend/notes/components/discussion_resolve_button_spec.js +++ b/spec/frontend/notes/components/discussion_resolve_button_spec.js @@ -7,7 +7,7 @@ const buttonTitle = 'Resolve discussion'; describe('resolveDiscussionButton', () => { let wrapper; - const factory = options => { + const factory = (options) => { wrapper = shallowMount(resolveDiscussionButton, { ...options, }); diff --git a/spec/frontend/notes/components/email_participants_warning_spec.js b/spec/frontend/notes/components/email_participants_warning_spec.js new file mode 100644 index 00000000000..ab1a6b152a4 --- /dev/null +++ b/spec/frontend/notes/components/email_participants_warning_spec.js @@ -0,0 +1,70 @@ +import { mount } from '@vue/test-utils'; +import EmailParticipantsWarning from '~/notes/components/email_participants_warning.vue'; + +describe('Email Participants Warning Component', () => { + let wrapper; + + afterEach(() => { + wrapper.destroy(); + wrapper = null; + }); + + const findMoreButton = () => wrapper.find('button'); + + const createWrapper = (emails) => { + wrapper = mount(EmailParticipantsWarning, { + propsData: { emails }, + }); + }; + + describe('with 3 or less emails', () => { + beforeEach(() => { + createWrapper(['a@gitlab.com', 'b@gitlab.com', 'c@gitlab.com']); + }); + + it('more button does not exist', () => { + expect(findMoreButton().exists()).toBe(false); + }); + + it('all emails are displayed', () => { + expect(wrapper.text()).toBe( + 'a@gitlab.com, b@gitlab.com, and c@gitlab.com will be notified of your comment.', + ); + }); + }); + + describe('with more than 3 emails', () => { + beforeEach(() => { + createWrapper(['a@gitlab.com', 'b@gitlab.com', 'c@gitlab.com', 'd@gitlab.com']); + }); + + it('only displays first 3 emails', () => { + expect(wrapper.text()).toContain('a@gitlab.com, b@gitlab.com, c@gitlab.com'); + expect(wrapper.text()).not.toContain('d@gitlab.com'); + }); + + it('more button does exist', () => { + expect(findMoreButton().exists()).toBe(true); + }); + + it('more button displays the correct wordage', () => { + expect(findMoreButton().text()).toBe('and 1 more'); + }); + + describe('when more button clicked', () => { + beforeEach(() => { + findMoreButton().trigger('click'); + }); + + it('more button no longer exists', () => { + expect(findMoreButton().exists()).toBe(false); + }); + + it('all emails are displayed', () => { + expect(wrapper.text()).toBe( + 'a@gitlab.com, b@gitlab.com, c@gitlab.com, and d@gitlab.com will be notified of your comment.', + ); + }); + }); + }); +}); diff --git a/spec/frontend/notes/components/multiline_comment_form_spec.js b/spec/frontend/notes/components/multiline_comment_form_spec.js new file mode 100644 index 00000000000..081fd6e10ef --- /dev/null +++ b/spec/frontend/notes/components/multiline_comment_form_spec.js @@ -0,0 +1,89 @@ +import Vue from 'vue'; +import Vuex from 'vuex'; +import { mount } from '@vue/test-utils'; +import { GlFormSelect } from '@gitlab/ui'; +import MultilineCommentForm from '~/notes/components/multiline_comment_form.vue'; +import notesModule from '~/notes/stores/modules'; + +describe('MultilineCommentForm', () => { + Vue.use(Vuex); + const setSelectedCommentPosition = jest.fn(); + const testLine = { + line_code: 'test', + type: 'test', + old_line: 'test', + new_line: 'test', + }; + + const createWrapper = (props = {}, state) => { + setSelectedCommentPosition.mockReset(); + + const store = new Vuex.Store({ + modules: { notes: notesModule() }, + actions: { setSelectedCommentPosition }, + }); + if (state) store.replaceState({ ...store.state, ...state }); + + const propsData = { + line: { ...testLine }, + commentLineOptions: [{ text: '1' }], + ...props, + }; + return mount(MultilineCommentForm, { propsData, store }); + }; + + describe('created', () => { + it('sets commentLineStart to line', () => { + const line = { ...testLine }; + const wrapper = createWrapper({ line }); + + expect(wrapper.vm.commentLineStart).toEqual(line); + expect(setSelectedCommentPosition).toHaveBeenCalled(); + }); + + it('sets commentLineStart to lineRange', () => { + const lineRange = { + start: { ...testLine }, + }; + const wrapper = createWrapper({ lineRange }); + + expect(wrapper.vm.commentLineStart).toEqual(lineRange.start); + expect(setSelectedCommentPosition).toHaveBeenCalled(); + }); + + it('sets commentLineStart to selectedCommentPosition', () => { + const notes = { + selectedCommentPosition: { + start: { ...testLine }, + }, + }; + const wrapper = createWrapper({}, { notes }); + + expect(wrapper.vm.commentLineStart).toEqual(wrapper.vm.selectedCommentPosition.start); + expect(setSelectedCommentPosition).not.toHaveBeenCalled(); + }); + }); + + describe('destroyed', () => { + it('calls setSelectedCommentPosition', () => { + const wrapper = createWrapper(); + wrapper.destroy(); + + // Once during created, once during destroyed + expect(setSelectedCommentPosition).toHaveBeenCalledTimes(2); + }); + }); + + it('handles changing the start line', () => { + const line = { ...testLine }; + const wrapper = createWrapper({ line }); + const glSelect = wrapper.findComponent(GlFormSelect); + + glSelect.vm.$emit('change', { ...testLine }); + + expect(wrapper.vm.commentLineStart).toEqual(line); + expect(wrapper.emitted('input')).toBeTruthy(); + // Once during created, once during updateCommentLineStart + expect(setSelectedCommentPosition).toHaveBeenCalledTimes(2); + }); +}); diff --git a/spec/frontend/notes/components/multiline_comment_utils_spec.js b/spec/frontend/notes/components/multiline_comment_utils_spec.js index 99b33e7cd5f..05faff02a6c 100644 --- a/spec/frontend/notes/components/multiline_comment_utils_spec.js +++ b/spec/frontend/notes/components/multiline_comment_utils_spec.js @@ -7,7 +7,7 @@ import { describe('Multiline comment utilities', () => { describe('get start & end line numbers', () => { - const lineRanges = ['old', 'new', null].map(type => ({ + const lineRanges = ['old', 'new', null].map((type) => ({ start: { new_line: 1, old_line: 1, type }, end: { new_line: 2, old_line: 2, type }, })); @@ -35,7 +35,7 @@ describe('Multiline comment utilities', () => { }); }); const inlineDiffLines = [{ line_code: '1' }, { line_code: '2' }, { line_code: '3' }]; - const parallelDiffLines = inlineDiffLines.map(line => ({ + const parallelDiffLines = inlineDiffLines.map((line) => ({ left: { ...line }, right: { ...line }, })); diff --git a/spec/frontend/notes/components/note_actions_spec.js b/spec/frontend/notes/components/note_actions_spec.js index f01c6c6b84e..3cfc1445cb8 100644 --- a/spec/frontend/notes/components/note_actions_spec.js +++ b/spec/frontend/notes/components/note_actions_spec.js @@ -65,23 +65,11 @@ describe('noteActions', () => { }); it('should render noteable author badge', () => { - expect( - wrapper - .findAll('.note-role') - .at(0) - .text() - .trim(), - ).toEqual('Author'); + expect(wrapper.findAll('.note-role').at(0).text().trim()).toEqual('Author'); }); it('should render access level badge', () => { - expect( - wrapper - .findAll('.note-role') - .at(1) - .text() - .trim(), - ).toEqual(props.accessLevel); + expect(wrapper.findAll('.note-role').at(1).text().trim()).toEqual(props.accessLevel); }); it('should render contributor badge', () => { @@ -91,13 +79,7 @@ describe('noteActions', () => { }); return wrapper.vm.$nextTick().then(() => { - expect( - wrapper - .findAll('.note-role') - .at(1) - .text() - .trim(), - ).toBe('Contributor'); + expect(wrapper.findAll('.note-role').at(1).text().trim()).toBe('Contributor'); }); }); @@ -119,7 +101,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', (done) => { wrapper.setProps({ ...props, author: { @@ -145,7 +127,7 @@ describe('noteActions', () => { expect(wrapper.find('.js-note-delete').exists()).toBe(true); }); - it('closes tooltip when dropdown opens', done => { + it('closes tooltip when dropdown opens', (done) => { wrapper.find('.more-actions-toggle').trigger('click'); const rootWrapper = createWrapper(wrapper.vm.$root); diff --git a/spec/frontend/notes/components/note_attachment_spec.js b/spec/frontend/notes/components/note_attachment_spec.js index 9d1051676e1..d47c2beaaf8 100644 --- a/spec/frontend/notes/components/note_attachment_spec.js +++ b/spec/frontend/notes/components/note_attachment_spec.js @@ -7,7 +7,7 @@ describe('Issue note attachment', () => { const findImage = () => wrapper.find({ ref: 'attachmentImage' }); const findUrl = () => wrapper.find({ ref: 'attachmentUrl' }); - const createComponent = attachment => { + const createComponent = (attachment) => { wrapper = shallowMount(NoteAttachment, { propsData: { attachment, diff --git a/spec/frontend/notes/components/note_awards_list_spec.js b/spec/frontend/notes/components/note_awards_list_spec.js index 5ab183e5452..13a817902e6 100644 --- a/spec/frontend/notes/components/note_awards_list_spec.js +++ b/spec/frontend/notes/components/note_awards_list_spec.js @@ -1,6 +1,6 @@ import Vue from 'vue'; import AxiosMockAdapter from 'axios-mock-adapter'; -import { TEST_HOST } from 'jest/helpers/test_constants'; +import { TEST_HOST } from 'helpers/test_constants'; import axios from '~/lib/utils/axios_utils'; import createStore from '~/notes/stores'; import awardsNote from '~/notes/components/note_awards_list.vue'; @@ -106,7 +106,7 @@ describe('note_awards_list component', () => { awardsMock = [...new Array(1)].map(createAwardEmoji); mountComponent(); - awardsMock.forEach(award => { + awardsMock.forEach((award) => { expect(findTooltip()).toContain(award.user.name); }); }); @@ -115,7 +115,7 @@ describe('note_awards_list component', () => { awardsMock = [...new Array(2)].map(createAwardEmoji); mountComponent(); - awardsMock.forEach(award => { + awardsMock.forEach((award) => { expect(findTooltip()).toContain(award.user.name); }); }); @@ -125,7 +125,7 @@ describe('note_awards_list component', () => { mountComponent(); // Testing only the first 10 awards since 11 onward will not be displayed. - awardsMock.slice(0, 10).forEach(award => { + awardsMock.slice(0, 10).forEach((award) => { expect(findTooltip()).toContain(award.user.name); }); }); diff --git a/spec/frontend/notes/components/note_body_spec.js b/spec/frontend/notes/components/note_body_spec.js index efad0785afe..3c11c266f90 100644 --- a/spec/frontend/notes/components/note_body_spec.js +++ b/spec/frontend/notes/components/note_body_spec.js @@ -38,7 +38,7 @@ describe('issue_note_body component', () => { }); describe('isEditing', () => { - beforeEach(done => { + beforeEach((done) => { vm.isEditing = true; Vue.nextTick(done); }); diff --git a/spec/frontend/notes/components/note_form_spec.js b/spec/frontend/notes/components/note_form_spec.js index cc434d6c952..e64a75bede9 100644 --- a/spec/frontend/notes/components/note_form_spec.js +++ b/spec/frontend/notes/components/note_form_spec.js @@ -1,4 +1,5 @@ -import { shallowMount, createLocalVue } from '@vue/test-utils'; +import { mount } from '@vue/test-utils'; +import { nextTick } from 'vue'; import createStore from '~/notes/stores'; import NoteForm from '~/notes/components/note_form.vue'; import batchComments from '~/batch_comments/stores/modules/batch_comments'; @@ -18,17 +19,14 @@ describe('issue_note_form component', () => { let props; const createComponentWrapper = () => { - const localVue = createLocalVue(); - return shallowMount(localVue.extend(NoteForm), { + return mount(NoteForm, { store, propsData: props, - // see https://gitlab.com/gitlab-org/gitlab-foss/issues/56317 for the following - localVue, }); }; beforeEach(() => { - getDraft.mockImplementation(key => { + getDraft.mockImplementation((key) => { if (key === dummyAutosaveKey) { return dummyDraft; } @@ -60,15 +58,14 @@ describe('issue_note_form component', () => { expect(wrapper.vm.noteHash).toBe(`#note_${props.noteId}`); }); - it('return note hash as `#` when `noteId` is empty', () => { + it('return note hash as `#` when `noteId` is empty', async () => { wrapper.setProps({ ...props, noteId: '', }); + await nextTick(); - return wrapper.vm.$nextTick().then(() => { - expect(wrapper.vm.noteHash).toBe('#'); - }); + expect(wrapper.vm.noteHash).toBe('#'); }); }); @@ -77,7 +74,7 @@ describe('issue_note_form component', () => { wrapper = createComponentWrapper(); }); - it('should show conflict message if note changes outside the component', () => { + it('should show conflict message if note changes outside the component', async () => { wrapper.setProps({ ...props, isEditing: true, @@ -87,17 +84,12 @@ describe('issue_note_form component', () => { const message = 'This comment has changed since you started editing, please review the updated comment to ensure information is not lost.'; - return wrapper.vm.$nextTick().then(() => { - const conflictWarning = wrapper.find('.js-conflict-edit-warning'); + await nextTick(); - expect(conflictWarning.exists()).toBe(true); - expect( - conflictWarning - .text() - .replace(/\s+/g, ' ') - .trim(), - ).toBe(message); - }); + const conflictWarning = wrapper.find('.js-conflict-edit-warning'); + + expect(conflictWarning.exists()).toBe(true); + expect(conflictWarning.text().replace(/\s+/g, ' ').trim()).toBe(message); }); }); @@ -161,36 +153,33 @@ describe('issue_note_form component', () => { }); describe('actions', () => { - it('should be possible to cancel', () => { - const cancelHandler = jest.fn(); + it('should be possible to cancel', async () => { wrapper.setProps({ ...props, isEditing: true, }); - wrapper.setMethods({ cancelHandler }); + await nextTick(); - return wrapper.vm.$nextTick().then(() => { - const cancelButton = wrapper.find('[data-testid="cancel"]'); - cancelButton.trigger('click'); + const cancelButton = wrapper.find('[data-testid="cancel"]'); + cancelButton.trigger('click'); + await nextTick(); - expect(cancelHandler).toHaveBeenCalledWith(true); - }); + expect(wrapper.emitted().cancelForm).toHaveLength(1); }); - it('should be possible to update the note', () => { + it('should be possible to update the note', async () => { wrapper.setProps({ ...props, isEditing: true, }); + await nextTick(); - return wrapper.vm.$nextTick().then(() => { - const textarea = wrapper.find('textarea'); - textarea.setValue('Foo'); - const saveButton = wrapper.find('.js-vue-issue-save'); - saveButton.trigger('click'); + const textarea = wrapper.find('textarea'); + textarea.setValue('Foo'); + const saveButton = wrapper.find('.js-vue-issue-save'); + saveButton.trigger('click'); - expect(wrapper.vm.isSubmitting).toBe(true); - }); + expect(wrapper.vm.isSubmitting).toBe(true); }); }); }); @@ -204,7 +193,7 @@ describe('issue_note_form component', () => { }); wrapper = createComponentWrapper(); - return wrapper.vm.$nextTick(); + return nextTick(); }); it('displays the draft in textarea', () => { @@ -222,7 +211,7 @@ describe('issue_note_form component', () => { }); wrapper = createComponentWrapper(); - return wrapper.vm.$nextTick(); + return nextTick(); }); it('leaves the textarea empty', () => { @@ -278,15 +267,14 @@ describe('issue_note_form component', () => { }); }); - it('should be possible to cancel', () => { + it('should be possible to cancel', async () => { jest.spyOn(wrapper.vm, 'cancelHandler'); - return wrapper.vm.$nextTick().then(() => { - const cancelButton = wrapper.find('[data-testid="cancelBatchCommentsEnabled"]'); - cancelButton.trigger('click'); + await nextTick(); + const cancelButton = wrapper.find('[data-testid="cancelBatchCommentsEnabled"]'); + cancelButton.trigger('click'); - expect(wrapper.vm.cancelHandler).toHaveBeenCalledWith(true); - }); + expect(wrapper.vm.cancelHandler).toHaveBeenCalledWith(true); }); it('shows resolve checkbox', () => { @@ -299,7 +287,7 @@ describe('issue_note_form component', () => { discussion: { ...discussionMock, notes: [ - ...discussionMock.notes.map(n => ({ + ...discussionMock.notes.map((n) => ({ ...n, resolvable: true, current_user: { ...n.current_user, can_resolve_discussion: false }, @@ -309,7 +297,7 @@ describe('issue_note_form component', () => { }, }); - await wrapper.vm.$nextTick(); + await nextTick(); expect(wrapper.find('.js-resolve-checkbox').exists()).toBe(false); }); @@ -317,7 +305,7 @@ describe('issue_note_form component', () => { it('hides actions for commits', () => { wrapper.setProps({ discussion: { for_commit: true } }); - return wrapper.vm.$nextTick(() => { + return nextTick(() => { expect(wrapper.find('.note-form-actions').text()).not.toContain('Start a review'); }); }); @@ -331,7 +319,7 @@ describe('issue_note_form component', () => { textarea.setValue('Foo'); textarea.trigger('keydown.enter', { metaKey: true }); - return wrapper.vm.$nextTick(() => { + return nextTick(() => { expect(wrapper.vm.handleAddToReview).toHaveBeenCalled(); }); }); diff --git a/spec/frontend/notes/components/note_header_spec.js b/spec/frontend/notes/components/note_header_spec.js index 1c6d0bafda8..132e3d8aa7e 100644 --- a/spec/frontend/notes/components/note_header_spec.js +++ b/spec/frontend/notes/components/note_header_spec.js @@ -41,7 +41,7 @@ describe('NoteHeader component', () => { }, }; - const createComponent = props => { + const createComponent = (props) => { wrapper = shallowMount(NoteHeader, { localVue, store: new Vuex.Store({ @@ -252,7 +252,7 @@ describe('NoteHeader component', () => { }); describe('when author username link is hovered', () => { - it('toggles hover specific CSS classes on author name link', done => { + it('toggles hover specific CSS classes on author name link', (done) => { createComponent({ author }); const authorUsernameLink = wrapper.find({ ref: 'authorUsernameLink' }); diff --git a/spec/frontend/notes/components/noteable_discussion_spec.js b/spec/frontend/notes/components/noteable_discussion_spec.js index 1c6603899d3..b87c6cd7f2b 100644 --- a/spec/frontend/notes/components/noteable_discussion_spec.js +++ b/spec/frontend/notes/components/noteable_discussion_spec.js @@ -1,8 +1,10 @@ -import { mount, createLocalVue } from '@vue/test-utils'; +import { nextTick } from 'vue'; +import { mount } 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 NoteableDiscussion from '~/notes/components/noteable_discussion.vue'; +import DiscussionNotes from '~/notes/components/discussion_notes.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'; @@ -17,8 +19,6 @@ import { const discussionWithTwoUnresolvedNotes = 'merge_requests/resolved_diff_discussion.json'; -const localVue = createLocalVue(); - describe('noteable_discussion component', () => { let store; let wrapper; @@ -32,10 +32,9 @@ describe('noteable_discussion component', () => { store.dispatch('setNoteableData', noteableDataMock); store.dispatch('setNotesData', notesDataMock); - wrapper = mount(localVue.extend(noteableDiscussion), { + wrapper = mount(NoteableDiscussion, { store, propsData: { discussion: discussionMock }, - localVue, }); }); @@ -47,63 +46,58 @@ describe('noteable_discussion component', () => { expect(wrapper.find('.discussion-header').exists()).toBe(false); }); - it('should render thread header', () => { + it('should render thread header', async () => { const discussion = { ...discussionMock }; discussion.diff_file = mockDiffFile; discussion.diff_discussion = true; discussion.expanded = false; wrapper.setProps({ discussion }); + await nextTick(); - return wrapper.vm.$nextTick().then(() => { - expect(wrapper.find('.discussion-header').exists()).toBe(true); - }); + expect(wrapper.find('.discussion-header').exists()).toBe(true); }); describe('actions', () => { - it('should toggle reply form', () => { - const replyPlaceholder = wrapper.find(ReplyPlaceholder); + it('should toggle reply form', async () => { + await nextTick(); - return wrapper.vm - .$nextTick() - .then(() => { - expect(wrapper.vm.isReplying).toEqual(false); + expect(wrapper.vm.isReplying).toEqual(false); - replyPlaceholder.vm.$emit('onClick'); - }) - .then(() => wrapper.vm.$nextTick()) - .then(() => { - expect(wrapper.vm.isReplying).toEqual(true); + const replyPlaceholder = wrapper.find(ReplyPlaceholder); + replyPlaceholder.vm.$emit('onClick'); + await nextTick(); - const noteForm = wrapper.find(NoteForm); + expect(wrapper.vm.isReplying).toEqual(true); - expect(noteForm.exists()).toBe(true); + const noteForm = wrapper.find(NoteForm); - const noteFormProps = noteForm.props(); + expect(noteForm.exists()).toBe(true); - 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`); - }); + 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`); }); it('should expand discussion', async () => { - const expandDiscussion = jest.fn(); - const discussion = { ...discussionMock }; - discussion.expanded = false; + const discussion = { ...discussionMock, expanded: false }; wrapper.setProps({ discussion }); - wrapper.setMethods({ expandDiscussion }); + store.dispatch = jest.fn(); - await wrapper.vm.$nextTick(); + await nextTick(); - wrapper.vm.showReplyForm(); + wrapper.find(DiscussionNotes).vm.$emit('startReplying'); - await wrapper.vm.$nextTick(); + await nextTick(); - expect(expandDiscussion).toHaveBeenCalledWith({ discussionId: discussion.id }); + expect(store.dispatch).toHaveBeenCalledWith('expandDiscussion', { + discussionId: discussion.id, + }); }); it('does not render jump to thread button', () => { @@ -132,7 +126,7 @@ describe('noteable_discussion component', () => { ...getJSONFixture(discussionWithTwoUnresolvedNotes)[0], expanded: true, }; - discussion.notes = discussion.notes.map(note => ({ + discussion.notes = discussion.notes.map((note) => ({ ...note, resolved: false, current_user: { @@ -143,7 +137,7 @@ describe('noteable_discussion component', () => { wrapper.setProps({ discussion }); - return wrapper.vm.$nextTick(); + return nextTick(); }); it('displays a button to resolve with issue', () => { @@ -169,10 +163,9 @@ describe('noteable_discussion component', () => { window.gon.current_user_id = userDataMock.id; store.dispatch('setUserData', userDataMock); - wrapper = mount(localVue.extend(noteableDiscussion), { + wrapper = mount(NoteableDiscussion, { store, propsData: { discussion: discussionMock }, - localVue, }); }); @@ -188,10 +181,9 @@ describe('noteable_discussion component', () => { store.dispatch('setNoteableData', loggedOutnoteableData); store.dispatch('setNotesData', notesDataMock); - wrapper = mount(localVue.extend(noteableDiscussion), { + wrapper = mount(NoteableDiscussion, { store, propsData: { discussion: discussionMock }, - localVue, }); }); diff --git a/spec/frontend/notes/components/noteable_note_spec.js b/spec/frontend/notes/components/noteable_note_spec.js index a08e86d92d3..6f06665f412 100644 --- a/spec/frontend/notes/components/noteable_note_spec.js +++ b/spec/frontend/notes/components/noteable_note_spec.js @@ -208,7 +208,7 @@ describe('issue_note', () => { expect(noteBodyProps.helpPagePath).toBe(''); }); - it('prevents note preview xss', done => { + it('prevents note preview xss', (done) => { const imgSrc = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7'; const noteBody = ``; const alertSpy = jest.spyOn(window, 'alert'); @@ -230,7 +230,7 @@ describe('issue_note', () => { }); describe('cancel edit', () => { - it('restores content of updated note', done => { + it('restores content of updated note', (done) => { const updatedText = 'updated note text'; store.hotUpdate({ actions: { diff --git a/spec/frontend/notes/components/notes_app_spec.js b/spec/frontend/notes/components/notes_app_spec.js index e905a12919e..e495a4738e0 100644 --- a/spec/frontend/notes/components/notes_app_spec.js +++ b/spec/frontend/notes/components/notes_app_spec.js @@ -36,16 +36,16 @@ describe('note_app', () => { const getComponentOrder = () => { return wrapper .findAll('#notes-list,.js-comment-form') - .wrappers.map(node => (node.is(CommentForm) ? TYPE_COMMENT_FORM : TYPE_NOTES_LIST)); + .wrappers.map((node) => (node.is(CommentForm) ? TYPE_COMMENT_FORM : TYPE_NOTES_LIST)); }; /** * waits for fetchNotes() to complete */ const waitForDiscussionsRequest = () => - new Promise(resolve => { + new Promise((resolve) => { const { vm } = wrapper.find(NotesApp); - const unwatch = vm.$watch('isFetching', isFetching => { + const unwatch = vm.$watch('isFetching', (isFetching) => { if (isFetching) { return; } @@ -129,18 +129,15 @@ describe('note_app', () => { '/gitlab-org/gitlab-foss/issues/26/discussions.json' ][0].notes[0]; - expect( - wrapper - .find('.main-notes-list .note-header-author-name') - .text() - .trim(), - ).toEqual(note.author.name); + expect(wrapper.find('.main-notes-list .note-header-author-name').text().trim()).toEqual( + note.author.name, + ); expect(wrapper.find('.main-notes-list .note-text').html()).toContain(note.note_html); }); it('should render form', () => { - expect(wrapper.find('.js-main-target-form').name()).toEqual('form'); + expect(wrapper.find('.js-main-target-form').element.tagName).toBe('FORM'); expect(wrapper.find('.js-main-target-form textarea').attributes('placeholder')).toEqual( 'Write a comment or drag your files here…', ); @@ -205,7 +202,7 @@ describe('note_app', () => { }); it('should render form', () => { - expect(wrapper.find('.js-main-target-form').name()).toEqual('form'); + expect(wrapper.find('.js-main-target-form').element.tagName).toBe('FORM'); expect(wrapper.find('.js-main-target-form textarea').attributes('placeholder')).toEqual( 'Write a comment or drag your files here…', ); @@ -272,23 +269,15 @@ describe('note_app', () => { it('should render markdown docs url', () => { const { markdownDocsPath } = mockData.notesDataMock; - expect( - wrapper - .find(`a[href="${markdownDocsPath}"]`) - .text() - .trim(), - ).toEqual('Markdown'); + expect(wrapper.find(`a[href="${markdownDocsPath}"]`).text().trim()).toEqual('Markdown'); }); it('should render quick action docs url', () => { const { quickActionsDocsPath } = mockData.notesDataMock; - expect( - wrapper - .find(`a[href="${quickActionsDocsPath}"]`) - .text() - .trim(), - ).toEqual('quick actions'); + expect(wrapper.find(`a[href="${quickActionsDocsPath}"]`).text().trim()).toEqual( + 'quick actions', + ); }); }); @@ -304,12 +293,9 @@ describe('note_app', () => { const { markdownDocsPath } = mockData.notesDataMock; return Vue.nextTick().then(() => { - expect( - wrapper - .find(`.edit-note a[href="${markdownDocsPath}"]`) - .text() - .trim(), - ).toEqual('Markdown is supported'); + expect(wrapper.find(`.edit-note a[href="${markdownDocsPath}"]`).text().trim()).toEqual( + 'Markdown is supported', + ); }); }); diff --git a/spec/frontend/notes/components/toggle_replies_widget_spec.js b/spec/frontend/notes/components/toggle_replies_widget_spec.js index b4f68b039cf..409e1bc3951 100644 --- a/spec/frontend/notes/components/toggle_replies_widget_spec.js +++ b/spec/frontend/notes/components/toggle_replies_widget_spec.js @@ -3,7 +3,7 @@ import mountComponent from 'helpers/vue_mount_component_helper'; import toggleRepliesWidget from '~/notes/components/toggle_replies_widget.vue'; import { note } from '../mock_data'; -const deepCloneObject = obj => JSON.parse(JSON.stringify(obj)); +const deepCloneObject = (obj) => JSON.parse(JSON.stringify(obj)); describe('toggle replies widget for notes', () => { let vm; -- cgit v1.2.1