diff options
Diffstat (limited to 'spec/frontend/notes')
-rw-r--r-- | spec/frontend/notes/components/comment_field_layout_spec.js | 4 | ||||
-rw-r--r-- | spec/frontend/notes/components/comment_form_spec.js | 32 | ||||
-rw-r--r-- | spec/frontend/notes/components/note_body_spec.js | 35 | ||||
-rw-r--r-- | spec/frontend/notes/components/note_header_spec.js | 16 | ||||
-rw-r--r-- | spec/frontend/notes/components/noteable_discussion_spec.js | 19 | ||||
-rw-r--r-- | spec/frontend/notes/components/notes_app_spec.js | 4 | ||||
-rw-r--r-- | spec/frontend/notes/mock_data.js | 10 | ||||
-rw-r--r-- | spec/frontend/notes/stores/actions_spec.js | 34 | ||||
-rw-r--r-- | spec/frontend/notes/stores/mutation_spec.js | 12 |
9 files changed, 124 insertions, 42 deletions
diff --git a/spec/frontend/notes/components/comment_field_layout_spec.js b/spec/frontend/notes/components/comment_field_layout_spec.js index 90c989540b9..d69c2c4adfa 100644 --- a/spec/frontend/notes/components/comment_field_layout_spec.js +++ b/spec/frontend/notes/components/comment_field_layout_spec.js @@ -135,14 +135,14 @@ describe('Comment Field Layout Component', () => { }); }); - describe('issue has email participants, but note is confidential', () => { + describe('issue has email participants, but note is internal', () => { it('does not show EmailParticipantsWarning', () => { createWrapper({ noteableData: { ...noteableDataMock, issue_email_participants: [{ email: 'someone@gitlab.com' }], }, - noteIsConfidential: true, + isInternalNote: true, }); expect(findEmailParticipantsWarning().exists()).toBe(false); diff --git a/spec/frontend/notes/components/comment_form_spec.js b/spec/frontend/notes/components/comment_form_spec.js index ba5d4d27e55..116016ecae2 100644 --- a/spec/frontend/notes/components/comment_form_spec.js +++ b/spec/frontend/notes/components/comment_form_spec.js @@ -32,7 +32,7 @@ describe('issue_comment_form component', () => { const findTextArea = () => wrapper.findByTestId('comment-field'); const findAddToReviewButton = () => wrapper.findByTestId('add-to-review-button'); const findAddCommentNowButton = () => wrapper.findByTestId('add-comment-now-button'); - const findConfidentialNoteCheckbox = () => wrapper.findByTestId('confidential-note-checkbox'); + const findConfidentialNoteCheckbox = () => wrapper.findByTestId('internal-note-checkbox'); const findCommentTypeDropdown = () => wrapper.findComponent(CommentTypeDropdown); const findCommentButton = () => findCommentTypeDropdown().find('button'); const findErrorAlerts = () => wrapper.findAllComponents(GlAlert).wrappers; @@ -249,15 +249,15 @@ describe('issue_comment_form component', () => { describe('textarea', () => { describe('general', () => { it.each` - noteType | confidential | placeholder - ${'comment'} | ${false} | ${'Write a comment or drag your files here…'} - ${'internal note'} | ${true} | ${'Write an internal note or drag your files here…'} + noteType | noteIsInternal | placeholder + ${'comment'} | ${false} | ${'Write a comment or drag your files here…'} + ${'internal note'} | ${true} | ${'Write an internal note or drag your files here…'} `( 'should render textarea with placeholder for $noteType', - ({ confidential, placeholder }) => { + ({ noteIsInternal, placeholder }) => { mountComponent({ mountFunction: mount, - initialData: { noteIsConfidential: confidential }, + initialData: { noteIsInternal }, }); expect(findTextArea().attributes('placeholder')).toBe(placeholder); @@ -389,14 +389,14 @@ describe('issue_comment_form component', () => { }); it.each` - confidential | buttonText - ${false} | ${'Comment'} - ${true} | ${'Add internal note'} - `('renders comment button with text "$buttonText"', ({ confidential, buttonText }) => { + noteIsInternal | buttonText + ${false} | ${'Comment'} + ${true} | ${'Add internal note'} + `('renders comment button with text "$buttonText"', ({ noteIsInternal, buttonText }) => { mountComponent({ mountFunction: mount, - noteableData: createNotableDataMock({ confidential }), - initialData: { noteIsConfidential: confidential }, + noteableData: createNotableDataMock({ confidential: noteIsInternal }), + initialData: { noteIsInternal }, }); expect(findCommentButton().text()).toBe(buttonText); @@ -487,8 +487,8 @@ describe('issue_comment_form component', () => { await findCloseReopenButton().trigger('click'); - await nextTick; - await nextTick; + await nextTick(); + await nextTick(); expect(createFlash).toHaveBeenCalledWith({ message: `Something went wrong while closing the ${type}. Please try again later.`, @@ -523,8 +523,8 @@ describe('issue_comment_form component', () => { await findCloseReopenButton().trigger('click'); - await nextTick; - await nextTick; + await nextTick(); + await nextTick(); expect(createFlash).toHaveBeenCalledWith({ message: `Something went wrong while reopening the ${type}. Please try again later.`, diff --git a/spec/frontend/notes/components/note_body_spec.js b/spec/frontend/notes/components/note_body_spec.js index 378dcb97fab..0f765a8da87 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 Vuex from 'vuex'; +import { shallowMountExtended } from 'helpers/vue_test_utils_helper'; import { suggestionCommitMessage } from '~/diffs/store/getters'; import NoteBody from '~/notes/components/note_body.vue'; @@ -7,6 +7,7 @@ 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'; @@ -27,7 +28,7 @@ const createComponent = ({ mockStore.dispatch('setNotesData', notesData); } - return shallowMount(NoteBody, { + return shallowMountExtended(NoteBody, { store: mockStore || store, propsData: { note, @@ -58,6 +59,24 @@ 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', () => { beforeEach(() => { wrapper = createComponent({ props: { isEditing: true } }); @@ -86,6 +105,18 @@ describe('issue_note_body component', () => { // which is defined in `app/assets/javascripts/notes/mixins/autosave.js` expect(wrapper.vm.autosave.key).toEqual(autosaveKey); }); + + describe('isInternalNote', () => { + beforeEach(() => { + wrapper.setProps({ isInternalNote: true }); + }); + + it('should not have internal note classes', () => { + expect(wrapper.findByTestId('note-internal-container').classes()).not.toEqual( + INTERNAL_NOTE_CLASSES, + ); + }); + }); }); describe('commitMessage', () => { diff --git a/spec/frontend/notes/components/note_header_spec.js b/spec/frontend/notes/components/note_header_spec.js index 310a470aa18..ad2cf1c5a35 100644 --- a/spec/frontend/notes/components/note_header_spec.js +++ b/spec/frontend/notes/components/note_header_spec.js @@ -21,7 +21,7 @@ describe('NoteHeader component', () => { const findActionText = () => wrapper.find({ ref: 'actionText' }); const findTimestampLink = () => wrapper.find({ ref: 'noteTimestampLink' }); const findTimestamp = () => wrapper.find({ ref: 'noteTimestamp' }); - const findConfidentialIndicator = () => wrapper.findByTestId('internalNoteIndicator'); + const findInternalNoteIndicator = () => wrapper.findByTestId('internalNoteIndicator'); const findSpinner = () => wrapper.find({ ref: 'spinner' }); const findAuthorStatus = () => wrapper.find({ ref: 'authorStatus' }); @@ -283,20 +283,20 @@ describe('NoteHeader component', () => { }); }); - describe('with confidentiality indicator', () => { + describe('with internal note badge', () => { it.each` status | condition ${true} | ${'shows'} ${false} | ${'hides'} - `('$condition icon indicator when isConfidential is $status', ({ status }) => { - createComponent({ isConfidential: status }); - expect(findConfidentialIndicator().exists()).toBe(status); + `('$condition badge when isInternalNote is $status', ({ status }) => { + createComponent({ isInternalNote: status }); + expect(findInternalNoteIndicator().exists()).toBe(status); }); - it('shows confidential indicator tooltip for project context', () => { - createComponent({ isConfidential: true, noteableType: 'issue' }); + it('shows internal note badge tooltip for project context', () => { + createComponent({ isInternalNote: true, noteableType: 'issue' }); - expect(findConfidentialIndicator().attributes('title')).toBe( + expect(findInternalNoteIndicator().attributes('title')).toBe( 'This internal note will always remain confidential', ); }); diff --git a/spec/frontend/notes/components/noteable_discussion_spec.js b/spec/frontend/notes/components/noteable_discussion_spec.js index c46d3bbe5b2..ddfa77117ca 100644 --- a/spec/frontend/notes/components/noteable_discussion_spec.js +++ b/spec/frontend/notes/components/noteable_discussion_spec.js @@ -87,10 +87,27 @@ describe('noteable_discussion component', () => { expect(noteFormProps.discussion).toBe(discussionMock); expect(noteFormProps.line).toBe(null); - expect(noteFormProps.saveButtonTitle).toBe('Comment'); expect(noteFormProps.autosaveKey).toBe(`Note/Issue/${discussionMock.id}/Reply`); }); + it.each` + noteType | isNoteInternal | saveButtonTitle + ${'public'} | ${false} | ${'Reply'} + ${'internal'} | ${true} | ${'Reply internally'} + `( + 'reply button on form should have title "$saveButtonTitle" when note is $noteType', + async ({ isNoteInternal, saveButtonTitle }) => { + wrapper.setProps({ discussion: { ...discussionMock, confidential: isNoteInternal } }); + await nextTick(); + + const replyPlaceholder = wrapper.find(ReplyPlaceholder); + replyPlaceholder.vm.$emit('focus'); + await nextTick(); + + expect(wrapper.find(NoteForm).props('saveButtonTitle')).toBe(saveButtonTitle); + }, + ); + it('should expand discussion', async () => { const discussion = { ...discussionMock, expanded: false }; diff --git a/spec/frontend/notes/components/notes_app_spec.js b/spec/frontend/notes/components/notes_app_spec.js index 413ee815906..f4eb69e0d49 100644 --- a/spec/frontend/notes/components/notes_app_spec.js +++ b/spec/frontend/notes/components/notes_app_spec.js @@ -19,8 +19,6 @@ import '~/behaviors/markdown/render_gfm'; import OrderedLayout from '~/vue_shared/components/ordered_layout.vue'; import * as mockData from '../mock_data'; -jest.mock('~/user_popovers', () => jest.fn()); - setTestTimeout(1000); const TYPE_COMMENT_FORM = 'comment-form'; @@ -224,7 +222,7 @@ describe('note_app', () => { }); it('renders skeleton notes', () => { - expect(wrapper.find('.animation-container').exists()).toBe(true); + expect(wrapper.find('.gl-skeleton-loader-default-container').exists()).toBe(true); }); it('should render form', () => { diff --git a/spec/frontend/notes/mock_data.js b/spec/frontend/notes/mock_data.js index c7a6ca5eae3..9fa7166474a 100644 --- a/spec/frontend/notes/mock_data.js +++ b/spec/frontend/notes/mock_data.js @@ -785,7 +785,7 @@ export const notesWithDescriptionChanges = [ current_user: { can_edit: false, can_award_emoji: true }, resolved: false, resolved_by: null, - system_note_icon_name: 'pencil-square', + system_note_icon_name: 'pencil', discussion_id: '7f1feda384083eb31763366e6392399fde6f3f31', emoji_awardable: false, report_abuse_path: @@ -874,7 +874,7 @@ export const notesWithDescriptionChanges = [ current_user: { can_edit: false, can_award_emoji: true }, resolved: false, resolved_by: null, - system_note_icon_name: 'pencil-square', + system_note_icon_name: 'pencil', discussion_id: 'a21cf2e804acc3c60d07e37d75e395f5a9a4d044', emoji_awardable: false, report_abuse_path: @@ -918,7 +918,7 @@ export const notesWithDescriptionChanges = [ current_user: { can_edit: false, can_award_emoji: true }, resolved: false, resolved_by: null, - system_note_icon_name: 'pencil-square', + system_note_icon_name: 'pencil', discussion_id: '70411b08cdfc01f24187a06d77daa33464cb2620', emoji_awardable: false, report_abuse_path: @@ -1105,7 +1105,7 @@ export const collapsedSystemNotes = [ current_user: { can_edit: false, can_award_emoji: true }, resolved: false, resolved_by: null, - system_note_icon_name: 'pencil-square', + system_note_icon_name: 'pencil', discussion_id: 'a21cf2e804acc3c60d07e37d75e395f5a9a4d044', emoji_awardable: false, report_abuse_path: @@ -1149,7 +1149,7 @@ export const collapsedSystemNotes = [ current_user: { can_edit: false, can_award_emoji: true }, resolved: false, resolved_by: null, - system_note_icon_name: 'pencil-square', + system_note_icon_name: 'pencil', discussion_id: '70411b08cdfc01f24187a06d77daa33464cb2620', emoji_awardable: false, report_abuse_path: diff --git a/spec/frontend/notes/stores/actions_spec.js b/spec/frontend/notes/stores/actions_spec.js index ecb213590ad..38f29ac2559 100644 --- a/spec/frontend/notes/stores/actions_spec.js +++ b/spec/frontend/notes/stores/actions_spec.js @@ -404,13 +404,13 @@ describe('Actions Notes Store', () => { beforeEach(() => { axiosMock.onDelete(endpoint).replyOnce(200, {}); - document.body.setAttribute('data-page', ''); + document.body.dataset.page = ''; }); afterEach(() => { axiosMock.restore(); - document.body.setAttribute('data-page', ''); + document.body.dataset.page = ''; }); it('commits DELETE_NOTE and dispatches updateMergeRequestWidget', () => { @@ -440,7 +440,7 @@ describe('Actions Notes Store', () => { it('dispatches removeDiscussionsFromDiff on merge request page', () => { const note = { path: endpoint, id: 1 }; - document.body.setAttribute('data-page', 'projects:merge_requests:show'); + document.body.dataset.page = 'projects:merge_requests:show'; return testAction( actions.removeNote, @@ -473,13 +473,13 @@ describe('Actions Notes Store', () => { beforeEach(() => { axiosMock.onDelete(endpoint).replyOnce(200, {}); - document.body.setAttribute('data-page', ''); + document.body.dataset.page = ''; }); afterEach(() => { axiosMock.restore(); - document.body.setAttribute('data-page', ''); + document.body.dataset.page = ''; }); it('dispatches removeNote', () => { @@ -1382,6 +1382,29 @@ describe('Actions Notes Store', () => { ], ); }); + + it('dispatches `fetchDiscussionsBatch` action if `paginatedMrDiscussions` feature flag is enabled', () => { + window.gon = { features: { paginatedMrDiscussions: true } }; + + return testAction( + actions.fetchDiscussions, + { path: 'test-path', filter: 'test-filter', persistFilter: 'test-persist-filter' }, + null, + [], + [ + { + type: 'fetchDiscussionsBatch', + payload: { + config: { + params: { notes_filter: 'test-filter', persist_filter: 'test-persist-filter' }, + }, + path: 'test-path', + perPage: 20, + }, + }, + ], + ); + }); }); describe('fetchDiscussionsBatch', () => { @@ -1401,6 +1424,7 @@ describe('Actions Notes Store', () => { null, [ { type: mutationTypes.ADD_OR_UPDATE_DISCUSSIONS, payload: { discussion } }, + { type: mutationTypes.SET_DONE_FETCHING_BATCH_DISCUSSIONS, payload: true }, { type: mutationTypes.SET_FETCHING_DISCUSSIONS, payload: false }, ], [{ type: 'updateResolvableDiscussionsCounts' }], diff --git a/spec/frontend/notes/stores/mutation_spec.js b/spec/frontend/notes/stores/mutation_spec.js index da1547ab6e7..e0a0fc43ffe 100644 --- a/spec/frontend/notes/stores/mutation_spec.js +++ b/spec/frontend/notes/stores/mutation_spec.js @@ -883,4 +883,16 @@ describe('Notes Store mutations', () => { expect(state.discussions[0].position).toEqual(position); }); }); + + describe('SET_DONE_FETCHING_BATCH_DISCUSSIONS', () => { + it('should set doneFetchingBatchDiscussions', () => { + const state = { + doneFetchingBatchDiscussions: false, + }; + + mutations.SET_DONE_FETCHING_BATCH_DISCUSSIONS(state, true); + + expect(state.doneFetchingBatchDiscussions).toEqual(true); + }); + }); }); |