diff options
Diffstat (limited to 'spec/frontend/notes')
21 files changed, 148 insertions, 106 deletions
diff --git a/spec/frontend/notes/components/comment_field_layout_spec.js b/spec/frontend/notes/components/comment_field_layout_spec.js index d69c2c4adfa..6662492fd81 100644 --- a/spec/frontend/notes/components/comment_field_layout_spec.js +++ b/spec/frontend/notes/components/comment_field_layout_spec.js @@ -22,8 +22,8 @@ describe('Comment Field Layout Component', () => { confidential_issues_docs_path: CONFIDENTIAL_ISSUES_DOCS_PATH, }; - const findIssuableNoteWarning = () => wrapper.find(NoteableWarning); - const findEmailParticipantsWarning = () => wrapper.find(EmailParticipantsWarning); + const findIssuableNoteWarning = () => wrapper.findComponent(NoteableWarning); + const findEmailParticipantsWarning = () => wrapper.findComponent(EmailParticipantsWarning); const findErrorAlert = () => wrapper.findByTestId('comment-field-alert-container'); const createWrapper = (props = {}, slots = {}) => { diff --git a/spec/frontend/notes/components/diff_discussion_header_spec.js b/spec/frontend/notes/components/diff_discussion_header_spec.js index 7878737fd31..5800f68b114 100644 --- a/spec/frontend/notes/components/diff_discussion_header_spec.js +++ b/spec/frontend/notes/components/diff_discussion_header_spec.js @@ -1,6 +1,7 @@ -import { mount } from '@vue/test-utils'; +import { shallowMount } from '@vue/test-utils'; import { nextTick } from 'vue'; +import { GlAvatar, GlAvatarLink } from '@gitlab/ui'; import diffDiscussionHeader from '~/notes/components/diff_discussion_header.vue'; import createStore from '~/notes/stores'; @@ -15,7 +16,7 @@ describe('diff_discussion_header component', () => { window.mrTabs = {}; store = createStore(); - wrapper = mount(diffDiscussionHeader, { + wrapper = shallowMount(diffDiscussionHeader, { store, propsData: { discussion: discussionMock }, }); @@ -25,15 +26,25 @@ describe('diff_discussion_header component', () => { wrapper.destroy(); }); - it('should render user avatar', async () => { - const discussion = { ...discussionMock }; - discussion.diff_file = mockDiffFile; - discussion.diff_discussion = true; + describe('Avatar', () => { + const firstNoteAuthor = discussionMock.notes[0].author; + const findAvatarLink = () => wrapper.findComponent(GlAvatarLink); + const findAvatar = () => wrapper.findComponent(GlAvatar); - wrapper.setProps({ discussion }); + it('should render user avatar and user avatar link', () => { + expect(findAvatar().exists()).toBe(true); + expect(findAvatarLink().exists()).toBe(true); + }); + + it('renders avatar of the first note author', () => { + const props = findAvatar().props(); - await nextTick(); - expect(wrapper.find('.user-avatar-link').exists()).toBe(true); + expect(props).toMatchObject({ + src: firstNoteAuthor.avatar_url, + alt: firstNoteAuthor.name, + size: { default: 24, md: 32 }, + }); + }); }); describe('action text', () => { diff --git a/spec/frontend/notes/components/discussion_actions_spec.js b/spec/frontend/notes/components/discussion_actions_spec.js index 925dbcc09ec..d16c13d6fd3 100644 --- a/spec/frontend/notes/components/discussion_actions_spec.js +++ b/spec/frontend/notes/components/discussion_actions_spec.js @@ -47,9 +47,9 @@ describe('DiscussionActions', () => { it('renders reply placeholder, resolve discussion button, resolve with issue button and jump to next discussion button', () => { createComponent(); - expect(wrapper.find(ReplyPlaceholder).exists()).toBe(true); - expect(wrapper.find(ResolveDiscussionButton).exists()).toBe(true); - expect(wrapper.find(ResolveWithIssueButton).exists()).toBe(true); + expect(wrapper.findComponent(ReplyPlaceholder).exists()).toBe(true); + expect(wrapper.findComponent(ResolveDiscussionButton).exists()).toBe(true); + expect(wrapper.findComponent(ResolveWithIssueButton).exists()).toBe(true); }); it('only renders reply placholder if disccusion is not resolvable', () => { @@ -57,15 +57,15 @@ describe('DiscussionActions', () => { discussion.resolvable = false; createComponent({ discussion }); - expect(wrapper.find(ReplyPlaceholder).exists()).toBe(true); - expect(wrapper.find(ResolveDiscussionButton).exists()).toBe(false); - expect(wrapper.find(ResolveWithIssueButton).exists()).toBe(false); + expect(wrapper.findComponent(ReplyPlaceholder).exists()).toBe(true); + expect(wrapper.findComponent(ResolveDiscussionButton).exists()).toBe(false); + expect(wrapper.findComponent(ResolveWithIssueButton).exists()).toBe(false); }); it('does not render resolve with issue button if resolveWithIssuePath is falsy', () => { createComponent({ resolveWithIssuePath: '' }); - expect(wrapper.find(ResolveWithIssueButton).exists()).toBe(false); + expect(wrapper.findComponent(ResolveWithIssueButton).exists()).toBe(false); }); describe.each` @@ -82,8 +82,8 @@ describe('DiscussionActions', () => { }); it(shouldRender ? 'renders resolve buttons' : 'does not render resolve buttons', () => { - expect(wrapper.find(ResolveDiscussionButton).exists()).toBe(shouldRender); - expect(wrapper.find(ResolveWithIssueButton).exists()).toBe(shouldRender); + expect(wrapper.findComponent(ResolveDiscussionButton).exists()).toBe(shouldRender); + expect(wrapper.findComponent(ResolveWithIssueButton).exists()).toBe(shouldRender); }); }); }); @@ -95,7 +95,7 @@ describe('DiscussionActions', () => { createComponent({}, { attachTo: document.body }); jest.spyOn(wrapper.vm, '$emit'); - wrapper.find(ReplyPlaceholder).find('textarea').trigger('focus'); + wrapper.findComponent(ReplyPlaceholder).find('textarea').trigger('focus'); expect(wrapper.vm.$emit).toHaveBeenCalledWith('showReplyForm'); }); @@ -103,7 +103,7 @@ describe('DiscussionActions', () => { createComponent(); jest.spyOn(wrapper.vm, '$emit'); - wrapper.find(ResolveDiscussionButton).find('button').trigger('click'); + wrapper.findComponent(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 f016cef18e6..a7e2f1efa09 100644 --- a/spec/frontend/notes/components/discussion_counter_spec.js +++ b/spec/frontend/notes/components/discussion_counter_spec.js @@ -47,7 +47,7 @@ describe('DiscussionCounter component', () => { it('does not render', () => { wrapper = shallowMount(DiscussionCounter, { store, propsData: { blocksMerge: true } }); - expect(wrapper.find({ ref: 'discussionCounter' }).exists()).toBe(false); + expect(wrapper.findComponent({ ref: 'discussionCounter' }).exists()).toBe(false); }); }); @@ -57,7 +57,7 @@ describe('DiscussionCounter component', () => { store.dispatch('updateResolvableDiscussionsCounts'); wrapper = shallowMount(DiscussionCounter, { store, propsData: { blocksMerge: true } }); - expect(wrapper.find({ ref: 'discussionCounter' }).exists()).toBe(false); + expect(wrapper.findComponent({ ref: 'discussionCounter' }).exists()).toBe(false); }); }); @@ -77,7 +77,7 @@ describe('DiscussionCounter component', () => { updateStore(); wrapper = shallowMount(DiscussionCounter, { store, propsData: { blocksMerge: true } }); - expect(wrapper.find({ ref: 'discussionCounter' }).exists()).toBe(true); + expect(wrapper.findComponent({ ref: 'discussionCounter' }).exists()).toBe(true); }); it.each` @@ -103,7 +103,7 @@ describe('DiscussionCounter component', () => { updateStore({ resolvable: true, resolved }); wrapper = shallowMount(DiscussionCounter, { store, propsData: { blocksMerge: true } }); - expect(wrapper.findAll(GlButton)).toHaveLength(groupLength); + expect(wrapper.findAllComponents(GlButton)).toHaveLength(groupLength); }); }); diff --git a/spec/frontend/notes/components/discussion_filter_note_spec.js b/spec/frontend/notes/components/discussion_filter_note_spec.js index ad9a2e898eb..48f5030aa1a 100644 --- a/spec/frontend/notes/components/discussion_filter_note_spec.js +++ b/spec/frontend/notes/components/discussion_filter_note_spec.js @@ -31,14 +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.findAllComponents(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.findAllComponents(GlButton).at(1).vm.$emit('click'); expect(eventHub.$emit).toHaveBeenCalledWith('dropdownSelect', 1); }); diff --git a/spec/frontend/notes/components/discussion_notes_spec.js b/spec/frontend/notes/components/discussion_notes_spec.js index 3506b6ac9f3..1b8b6bec490 100644 --- a/spec/frontend/notes/components/discussion_notes_spec.js +++ b/spec/frontend/notes/components/discussion_notes_spec.js @@ -61,13 +61,13 @@ describe('DiscussionNotes', () => { it('renders an element for each note in the discussion', () => { createComponent(); const notesCount = discussionMock.notes.length; - const els = wrapper.findAll(NoteableNote); + const els = wrapper.findAllComponents(NoteableNote); expect(els.length).toBe(notesCount); }); it('renders one element if replies groupping is enabled', () => { createComponent({ shouldGroupReplies: true }); - const els = wrapper.findAll(NoteableNote); + const els = wrapper.findAllComponents(NoteableNote); expect(els.length).toBe(1); }); diff --git a/spec/frontend/notes/components/discussion_reply_placeholder_spec.js b/spec/frontend/notes/components/discussion_reply_placeholder_spec.js index 3932f818c4e..971e3987929 100644 --- a/spec/frontend/notes/components/discussion_reply_placeholder_spec.js +++ b/spec/frontend/notes/components/discussion_reply_placeholder_spec.js @@ -15,7 +15,7 @@ describe('ReplyPlaceholder', () => { }); }; - const findTextarea = () => wrapper.find({ ref: 'textarea' }); + const findTextarea = () => wrapper.findComponent({ ref: 'textarea' }); afterEach(() => { wrapper.destroy(); diff --git a/spec/frontend/notes/components/discussion_resolve_button_spec.js b/spec/frontend/notes/components/discussion_resolve_button_spec.js index ca0c0ca6de8..17c3523cf48 100644 --- a/spec/frontend/notes/components/discussion_resolve_button_spec.js +++ b/spec/frontend/notes/components/discussion_resolve_button_spec.js @@ -28,7 +28,7 @@ describe('resolveDiscussionButton', () => { }); it('should emit a onClick event on button click', async () => { - const button = wrapper.find(GlButton); + const button = wrapper.findComponent(GlButton); button.vm.$emit('click'); @@ -39,7 +39,7 @@ describe('resolveDiscussionButton', () => { }); it('should contain the provided button title', () => { - const button = wrapper.find(GlButton); + const button = wrapper.findComponent(GlButton); expect(button.text()).toContain(buttonTitle); }); @@ -52,7 +52,7 @@ describe('resolveDiscussionButton', () => { }, }); - const button = wrapper.find(GlButton); + const button = wrapper.findComponent(GlButton); expect(button.props('loading')).toEqual(true); }); @@ -65,7 +65,7 @@ describe('resolveDiscussionButton', () => { }, }); - const button = wrapper.find(GlButton); + const button = wrapper.findComponent(GlButton); 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 5bc6282db03..71406eeb7b4 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 @@ -20,7 +20,7 @@ describe('ResolveWithIssueButton', () => { }); it('it should have a link with the provided link property as href', () => { - const button = wrapper.find(GlButton); + const button = wrapper.findComponent(GlButton); expect(button.attributes().href).toBe(url); }); diff --git a/spec/frontend/notes/components/note_actions/reply_button_spec.js b/spec/frontend/notes/components/note_actions/reply_button_spec.js index 4993ded365d..20b32b8c178 100644 --- a/spec/frontend/notes/components/note_actions/reply_button_spec.js +++ b/spec/frontend/notes/components/note_actions/reply_button_spec.js @@ -15,7 +15,7 @@ describe('ReplyButton', () => { }); it('emits startReplying on click', () => { - wrapper.find(GlButton).vm.$emit('click'); + wrapper.findComponent(GlButton).vm.$emit('click'); expect(wrapper.emitted('startReplying')).toEqual([[]]); }); diff --git a/spec/frontend/notes/components/note_actions_spec.js b/spec/frontend/notes/components/note_actions_spec.js index bf5a6b4966a..cbe11c20798 100644 --- a/spec/frontend/notes/components/note_actions_spec.js +++ b/spec/frontend/notes/components/note_actions_spec.js @@ -16,7 +16,7 @@ describe('noteActions', () => { let actions; let axiosMock; - const findUserAccessRoleBadge = (idx) => wrapper.findAll(UserAccessRoleBadge).at(idx); + const findUserAccessRoleBadge = (idx) => wrapper.findAllComponents(UserAccessRoleBadge).at(idx); const findUserAccessRoleBadgeText = (idx) => findUserAccessRoleBadge(idx).text().trim(); const mountNoteActions = (propsData, computed) => { @@ -159,7 +159,7 @@ describe('noteActions', () => { }); }); - describe('when a user has access to edit an issue', () => { + describe('when a user can set metadata of an issue', () => { const testButtonClickTriggersAction = () => { axiosMock.onPut(`${TEST_HOST}/api/v4/projects/group/project/issues/1`).reply(() => { expect(actions.updateAssignees).toHaveBeenCalled(); @@ -176,7 +176,7 @@ describe('noteActions', () => { }); store.state.noteableData = { current_user: { - can_update: true, + can_set_issue_metadata: true, }, }; store.state.userData = userDataMock; @@ -191,6 +191,31 @@ describe('noteActions', () => { it('should be possible to unassign the comment author', testButtonClickTriggersAction); }); + describe('when a user can update but not set metadata of an issue', () => { + beforeEach(() => { + wrapper = mountNoteActions(props, { + targetType: () => 'issue', + }); + store.state.noteableData = { + current_user: { + can_update: true, + can_set_issue_metadata: false, + }, + }; + store.state.userData = userDataMock; + }); + + afterEach(() => { + wrapper.destroy(); + axiosMock.restore(); + }); + + it('should not be possible to assign or unassign the comment author', () => { + const assignUserButton = wrapper.find('[data-testid="assign-user"]'); + expect(assignUserButton.exists()).toBe(false); + }); + }); + describe('when a user does not have access to edit an issue', () => { const testButtonDoesNotRender = () => { const assignUserButton = wrapper.find('[data-testid="assign-user"]'); @@ -241,7 +266,7 @@ describe('noteActions', () => { }); it('shows a reply button', () => { - const replyButton = wrapper.find({ ref: 'replyButton' }); + const replyButton = wrapper.findComponent({ ref: 'replyButton' }); expect(replyButton.exists()).toBe(true); }); @@ -256,7 +281,7 @@ describe('noteActions', () => { }); it('does not show a reply button', () => { - const replyButton = wrapper.find({ ref: 'replyButton' }); + const replyButton = wrapper.findComponent({ ref: 'replyButton' }); expect(replyButton.exists()).toBe(false); }); @@ -270,7 +295,7 @@ describe('noteActions', () => { }); it('should render the right resolve button title', () => { - const resolveButton = wrapper.find({ ref: 'resolveButton' }); + const resolveButton = wrapper.findComponent({ ref: 'resolveButton' }); expect(resolveButton.exists()).toBe(true); expect(resolveButton.attributes('title')).toBe('Thread stays unresolved'); diff --git a/spec/frontend/notes/components/note_attachment_spec.js b/spec/frontend/notes/components/note_attachment_spec.js index d47c2beaaf8..24632f8e427 100644 --- a/spec/frontend/notes/components/note_attachment_spec.js +++ b/spec/frontend/notes/components/note_attachment_spec.js @@ -4,8 +4,8 @@ import NoteAttachment from '~/notes/components/note_attachment.vue'; describe('Issue note attachment', () => { let wrapper; - const findImage = () => wrapper.find({ ref: 'attachmentImage' }); - const findUrl = () => wrapper.find({ ref: 'attachmentUrl' }); + const findImage = () => wrapper.findComponent({ ref: 'attachmentImage' }); + const findUrl = () => wrapper.findComponent({ ref: 'attachmentUrl' }); const createComponent = (attachment) => { wrapper = shallowMount(NoteAttachment, { diff --git a/spec/frontend/notes/components/note_body_spec.js b/spec/frontend/notes/components/note_body_spec.js index 0f765a8da87..c2e56d3e7a7 100644 --- a/spec/frontend/notes/components/note_body_spec.js +++ b/spec/frontend/notes/components/note_body_spec.js @@ -7,7 +7,6 @@ import NoteAwardsList from '~/notes/components/note_awards_list.vue'; import NoteForm from '~/notes/components/note_form.vue'; import createStore from '~/notes/stores'; import notes from '~/notes/stores/modules/index'; -import { INTERNAL_NOTE_CLASSES } from '~/notes/constants'; import Suggestions from '~/vue_shared/components/markdown/suggestions.vue'; @@ -59,22 +58,10 @@ describe('issue_note_body component', () => { expect(wrapper.findComponent(NoteAwardsList).exists()).toBe(true); }); - it('should not have internal note classes', () => { - expect(wrapper.findByTestId('note-internal-container').classes()).not.toEqual( - INTERNAL_NOTE_CLASSES, - ); - }); - describe('isInternalNote', () => { beforeEach(() => { wrapper = createComponent({ props: { isInternalNote: true } }); }); - - it('should have internal note classes', () => { - expect(wrapper.findByTestId('note-internal-container').classes()).toEqual( - INTERNAL_NOTE_CLASSES, - ); - }); }); describe('isEditing', () => { @@ -110,12 +97,6 @@ describe('issue_note_body component', () => { beforeEach(() => { wrapper.setProps({ isInternalNote: true }); }); - - it('should not have internal note classes', () => { - expect(wrapper.findByTestId('note-internal-container').classes()).not.toEqual( - INTERNAL_NOTE_CLASSES, - ); - }); }); }); @@ -162,7 +143,7 @@ describe('issue_note_body component', () => { }); it('passes the correct default placeholder commit message for a suggestion to the suggestions component', () => { - const commitMessage = wrapper.find(Suggestions).attributes('defaultcommitmessage'); + const commitMessage = wrapper.findComponent(Suggestions).attributes('defaultcommitmessage'); expect(commitMessage).toBe('branch/pathnameuseruser usertonabc11'); }); diff --git a/spec/frontend/notes/components/note_form_spec.js b/spec/frontend/notes/components/note_form_spec.js index 252c24d1117..fad04e9063d 100644 --- a/spec/frontend/notes/components/note_form_spec.js +++ b/spec/frontend/notes/components/note_form_spec.js @@ -6,6 +6,7 @@ import { getDraft, updateDraft } from '~/lib/utils/autosave'; import NoteForm from '~/notes/components/note_form.vue'; import createStore from '~/notes/stores'; import MarkdownField from '~/vue_shared/components/markdown/field.vue'; +import { AT_WHO_ACTIVE_CLASS } from '~/gfm_auto_complete'; import { noteableDataMock, notesDataMock, discussionMock, note } from '../mock_data'; jest.mock('~/lib/utils/autosave'); @@ -91,7 +92,7 @@ describe('issue_note_form component', () => { expect(conflictWarning.exists()).toBe(true); expect(conflictWarning.text().replace(/\s+/g, ' ').trim()).toBe(message); - expect(conflictWarning.find(GlLink).attributes('href')).toBe('#note_545'); + expect(conflictWarning.findComponent(GlLink).attributes('href')).toBe('#note_545'); }); }); @@ -133,7 +134,7 @@ describe('issue_note_form component', () => { it('should link to markdown docs', () => { const { markdownDocsPath } = notesDataMock; - const markdownField = wrapper.find(MarkdownField); + const markdownField = wrapper.findComponent(MarkdownField); const markdownFieldProps = markdownField.props(); expect(markdownFieldProps.markdownDocsPath).toBe(markdownDocsPath); @@ -201,6 +202,21 @@ describe('issue_note_form component', () => { expect(wrapper.emitted().cancelForm).toHaveLength(1); }); + it('will not cancel form if there is an active at-who-active class', async () => { + wrapper.setProps({ + ...props, + }); + await nextTick(); + + const textareaEl = wrapper.vm.$refs.textarea; + const cancelButton = findCancelButton(); + textareaEl.classList.add(AT_WHO_ACTIVE_CLASS); + cancelButton.vm.$emit('click'); + await nextTick(); + + expect(wrapper.emitted().cancelForm).toBeUndefined(); + }); + it('should be possible to update the note', async () => { wrapper.setProps({ ...props, diff --git a/spec/frontend/notes/components/note_header_spec.js b/spec/frontend/notes/components/note_header_spec.js index ad2cf1c5a35..43fbc5e26dc 100644 --- a/spec/frontend/notes/components/note_header_spec.js +++ b/spec/frontend/notes/components/note_header_spec.js @@ -15,15 +15,15 @@ const actions = { describe('NoteHeader component', () => { let wrapper; - const findActionsWrapper = () => wrapper.find({ ref: 'discussionActions' }); + const findActionsWrapper = () => wrapper.findComponent({ ref: 'discussionActions' }); const findToggleThreadButton = () => wrapper.findByTestId('thread-toggle'); - const findChevronIcon = () => wrapper.find({ ref: 'chevronIcon' }); - const findActionText = () => wrapper.find({ ref: 'actionText' }); - const findTimestampLink = () => wrapper.find({ ref: 'noteTimestampLink' }); - const findTimestamp = () => wrapper.find({ ref: 'noteTimestamp' }); + const findChevronIcon = () => wrapper.findComponent({ ref: 'chevronIcon' }); + const findActionText = () => wrapper.findComponent({ ref: 'actionText' }); + const findTimestampLink = () => wrapper.findComponent({ ref: 'noteTimestampLink' }); + const findTimestamp = () => wrapper.findComponent({ ref: 'noteTimestamp' }); const findInternalNoteIndicator = () => wrapper.findByTestId('internalNoteIndicator'); - const findSpinner = () => wrapper.find({ ref: 'spinner' }); - const findAuthorStatus = () => wrapper.find({ ref: 'authorStatus' }); + const findSpinner = () => wrapper.findComponent({ ref: 'spinner' }); + const findAuthorStatus = () => wrapper.findComponent({ ref: 'authorStatus' }); const statusHtml = '"<span class="user-status-emoji has-tooltip" title="foo bar" data-html="true" data-placement="top"><gl-emoji title="basketball and hoop" data-name="basketball" data-unicode-version="6.0">🏀</gl-emoji></span>"'; @@ -228,7 +228,7 @@ describe('NoteHeader component', () => { const dispatchEvent = jest.spyOn(wrapper.vm.$refs.authorNameLink, 'dispatchEvent'); - wrapper.find({ ref: 'authorUsernameLink' }).trigger('mouseenter'); + wrapper.findComponent({ ref: 'authorUsernameLink' }).trigger('mouseenter'); expect(dispatchEvent).toHaveBeenCalledWith(new Event('mouseenter')); }); @@ -238,7 +238,7 @@ describe('NoteHeader component', () => { const dispatchEvent = jest.spyOn(wrapper.vm.$refs.authorNameLink, 'dispatchEvent'); - wrapper.find({ ref: 'authorUsernameLink' }).trigger('mouseleave'); + wrapper.findComponent({ ref: 'authorUsernameLink' }).trigger('mouseleave'); expect(dispatchEvent).toHaveBeenCalledWith(new Event('mouseleave')); }); @@ -266,8 +266,8 @@ describe('NoteHeader component', () => { it('toggles hover specific CSS classes on author name link', async () => { createComponent({ author }); - const authorUsernameLink = wrapper.find({ ref: 'authorUsernameLink' }); - const authorNameLink = wrapper.find({ ref: 'authorNameLink' }); + const authorUsernameLink = wrapper.findComponent({ ref: 'authorUsernameLink' }); + const authorNameLink = wrapper.findComponent({ ref: 'authorNameLink' }); authorUsernameLink.trigger('mouseenter'); diff --git a/spec/frontend/notes/components/noteable_discussion_spec.js b/spec/frontend/notes/components/noteable_discussion_spec.js index 603db56a098..b34305688d9 100644 --- a/spec/frontend/notes/components/noteable_discussion_spec.js +++ b/spec/frontend/notes/components/noteable_discussion_spec.js @@ -73,13 +73,13 @@ describe('noteable_discussion component', () => { expect(wrapper.vm.isReplying).toEqual(false); - const replyPlaceholder = wrapper.find(ReplyPlaceholder); + const replyPlaceholder = wrapper.findComponent(ReplyPlaceholder); replyPlaceholder.vm.$emit('focus'); await nextTick(); expect(wrapper.vm.isReplying).toEqual(true); - const noteForm = wrapper.find(NoteForm); + const noteForm = wrapper.findComponent(NoteForm); expect(noteForm.exists()).toBe(true); @@ -100,11 +100,11 @@ describe('noteable_discussion component', () => { wrapper.setProps({ discussion: { ...discussionMock, confidential: isNoteInternal } }); await nextTick(); - const replyPlaceholder = wrapper.find(ReplyPlaceholder); + const replyPlaceholder = wrapper.findComponent(ReplyPlaceholder); replyPlaceholder.vm.$emit('focus'); await nextTick(); - expect(wrapper.find(NoteForm).props('saveButtonTitle')).toBe(saveButtonTitle); + expect(wrapper.findComponent(NoteForm).props('saveButtonTitle')).toBe(saveButtonTitle); }, ); @@ -116,7 +116,7 @@ describe('noteable_discussion component', () => { await nextTick(); - wrapper.find(DiscussionNotes).vm.$emit('startReplying'); + wrapper.findComponent(DiscussionNotes).vm.$emit('startReplying'); await nextTick(); @@ -139,7 +139,7 @@ describe('noteable_discussion component', () => { }); it('does not display a button to resolve with issue', () => { - const button = wrapper.find(ResolveWithIssueButton); + const button = wrapper.findComponent(ResolveWithIssueButton); expect(button.exists()).toBe(false); }); @@ -159,7 +159,7 @@ describe('noteable_discussion component', () => { }); it('displays a button to resolve with issue', () => { - const button = wrapper.find(ResolveWithIssueButton); + const button = wrapper.findComponent(ResolveWithIssueButton); expect(button.exists()).toBe(true); }); diff --git a/spec/frontend/notes/components/noteable_note_spec.js b/spec/frontend/notes/components/noteable_note_spec.js index 3350609bb90..e049c5bc0c8 100644 --- a/spec/frontend/notes/components/noteable_note_spec.js +++ b/spec/frontend/notes/components/noteable_note_spec.js @@ -285,11 +285,25 @@ describe('issue_note', () => { await waitForPromises(); expect(alertSpy).not.toHaveBeenCalled(); expect(wrapper.vm.note.note_html).toBe( - '<p><img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"></p>\n', + '<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7">', ); }); }); + describe('internal note', () => { + it('has internal note class for internal notes', () => { + createWrapper({ note: { ...note, confidential: true } }); + + expect(wrapper.classes()).toContain('internal-note'); + }); + + it('does not have internal note class for external notes', () => { + createWrapper({ note }); + + expect(wrapper.classes()).not.toContain('internal-note'); + }); + }); + describe('cancel edit', () => { beforeEach(() => { createWrapper(); @@ -357,7 +371,7 @@ describe('issue_note', () => { createWrapper(); updateActions(); wrapper.findComponent(NoteBody).vm.$emit('handleFormUpdate', params); - expect(wrapper.emitted('handleUpdateNote')).toBeTruthy(); + expect(wrapper.emitted('handleUpdateNote')).toHaveLength(1); }); it('does not stringify empty position', () => { diff --git a/spec/frontend/notes/components/notes_app_spec.js b/spec/frontend/notes/components/notes_app_spec.js index 36a68118fa7..d4cb07d97dc 100644 --- a/spec/frontend/notes/components/notes_app_spec.js +++ b/spec/frontend/notes/components/notes_app_spec.js @@ -4,7 +4,6 @@ import $ from 'jquery'; import { nextTick } from 'vue'; import { setHTMLFixture, resetHTMLFixture } from 'helpers/fixtures'; import setWindowLocation from 'helpers/set_window_location_helper'; -import { setTestTimeout } from 'helpers/timeout'; import waitForPromises from 'helpers/wait_for_promises'; import DraftNote from '~/batch_comments/components/draft_note.vue'; import batchComments from '~/batch_comments/stores/modules/batch_comments'; @@ -19,8 +18,6 @@ import '~/behaviors/markdown/render_gfm'; import OrderedLayout from '~/vue_shared/components/ordered_layout.vue'; import * as mockData from '../mock_data'; -setTestTimeout(1000); - const TYPE_COMMENT_FORM = 'comment-form'; const TYPE_NOTES_LIST = 'notes-list'; @@ -359,7 +356,7 @@ describe('note_app', () => { }); it('should listen hashchange event', () => { - const notesApp = wrapper.find(NotesApp); + const notesApp = wrapper.findComponent(NotesApp); const hash = 'some dummy hash'; jest.spyOn(urlUtility, 'getLocationHash').mockReturnValueOnce(hash); const setTargetNoteHash = jest.spyOn(notesApp.vm, 'setTargetNoteHash'); @@ -439,7 +436,7 @@ describe('note_app', () => { }); it('correctly finds only draft comments', () => { - const drafts = wrapper.findAll(DraftNote).wrappers; + const drafts = wrapper.findAllComponents(DraftNote).wrappers; expect(drafts.map((x) => x.props('draft'))).toEqual( mockData.draftComments.map(({ note }) => expect.objectContaining({ note })), diff --git a/spec/frontend/notes/components/sort_discussion_spec.js b/spec/frontend/notes/components/sort_discussion_spec.js index bde27b7e5fc..8b6e05da3c0 100644 --- a/spec/frontend/notes/components/sort_discussion_spec.js +++ b/spec/frontend/notes/components/sort_discussion_spec.js @@ -21,7 +21,7 @@ describe('Sort Discussion component', () => { }); }; - const findLocalStorageSync = () => wrapper.find(LocalStorageSync); + const findLocalStorageSync = () => wrapper.findComponent(LocalStorageSync); beforeEach(() => { store = createStore(); diff --git a/spec/frontend/notes/components/timeline_toggle_spec.js b/spec/frontend/notes/components/timeline_toggle_spec.js index 84fa3008835..cf79416d300 100644 --- a/spec/frontend/notes/components/timeline_toggle_spec.js +++ b/spec/frontend/notes/components/timeline_toggle_spec.js @@ -27,7 +27,7 @@ describe('Timeline toggle', () => { }); }; - const findGlButton = () => wrapper.find(GlButton); + const findGlButton = () => wrapper.findComponent(GlButton); beforeEach(() => { store = createStore(); diff --git a/spec/frontend/notes/deprecated_notes_spec.js b/spec/frontend/notes/deprecated_notes_spec.js index 40b124b9029..d5e2a189afe 100644 --- a/spec/frontend/notes/deprecated_notes_spec.js +++ b/spec/frontend/notes/deprecated_notes_spec.js @@ -7,7 +7,6 @@ import { loadHTMLFixture, resetHTMLFixture } from 'helpers/fixtures'; 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'; @@ -48,7 +47,6 @@ describe.skip('Old Notes (~/deprecated_notes.js)', () => { // random failures. // It seems that running tests in parallel increases failure rate. jest.setTimeout(4000); - setTestTimeoutOnce(4000); }); afterEach(async () => { @@ -510,7 +508,7 @@ describe.skip('Old Notes (~/deprecated_notes.js)', () => { notes.putEditFormInPlace($el); - expect(notes.glForm.enableGFM).toBeTruthy(); + expect(notes.glForm.enableGFM).toBe(''); }); }); @@ -783,21 +781,21 @@ describe.skip('Old Notes (~/deprecated_notes.js)', () => { const sampleComment = '/wip\n/milestone %1.0\n/merge\n/unassign Merging this'; const hasQuickActions = notes.hasQuickActions(sampleComment); - expect(hasQuickActions).toBeTruthy(); + expect(hasQuickActions).toBe(true); }); it('should return false when comment does NOT begin with a quick action', () => { const sampleComment = 'Hey, /unassign Merging this'; const hasQuickActions = notes.hasQuickActions(sampleComment); - expect(hasQuickActions).toBeFalsy(); + expect(hasQuickActions).toBe(false); }); it('should return false when comment does NOT have any quick actions', () => { const sampleComment = 'Looking good, Awesome!'; const hasQuickActions = notes.hasQuickActions(sampleComment); - expect(hasQuickActions).toBeFalsy(); + expect(hasQuickActions).toBe(false); }); }); @@ -887,14 +885,14 @@ describe.skip('Old Notes (~/deprecated_notes.js)', () => { expect($tempNote.prop('nodeName')).toEqual('LI'); expect($tempNote.attr('id')).toEqual(uniqueId); - expect($tempNote.hasClass('being-posted')).toBeTruthy(); - expect($tempNote.hasClass('fade-in-half')).toBeTruthy(); + expect($tempNote.hasClass('being-posted')).toBe(true); + expect($tempNote.hasClass('fade-in-half')).toBe(true); $tempNote.find('.timeline-icon > a, .note-header-info > a').each((i, el) => { expect(el.getAttribute('href')).toEqual(`/${currentUsername}`); }); expect($tempNote.find('.timeline-icon .avatar').attr('src')).toEqual(currentUserAvatar); - expect($tempNote.find('.timeline-content').hasClass('discussion')).toBeFalsy(); + expect($tempNote.find('.timeline-content').hasClass('discussion')).toBe(false); expect($tempNoteHeader.find('.d-none.d-sm-inline-block').text().trim()).toEqual( currentUserFullname, ); @@ -916,7 +914,7 @@ describe.skip('Old Notes (~/deprecated_notes.js)', () => { }); expect($tempNote.prop('nodeName')).toEqual('LI'); - expect($tempNote.find('.timeline-content').hasClass('discussion')).toBeTruthy(); + expect($tempNote.find('.timeline-content').hasClass('discussion')).toBe(true); }); it('should return a escaped user name', () => { @@ -954,8 +952,8 @@ describe.skip('Old Notes (~/deprecated_notes.js)', () => { expect($tempNote.prop('nodeName')).toEqual('LI'); expect($tempNote.attr('id')).toEqual(uniqueId); - expect($tempNote.hasClass('being-posted')).toBeTruthy(); - expect($tempNote.hasClass('fade-in-half')).toBeTruthy(); + expect($tempNote.hasClass('being-posted')).toBe(true); + expect($tempNote.hasClass('fade-in-half')).toBe(true); expect($tempNote.find('.timeline-content i').text().trim()).toEqual(sampleCommandDescription); }); }); |