diff options
Diffstat (limited to 'spec/frontend/notes')
8 files changed, 90 insertions, 36 deletions
diff --git a/spec/frontend/notes/components/comment_form_spec.js b/spec/frontend/notes/components/comment_form_spec.js index 002c4f206cb..8394d1d0ab2 100644 --- a/spec/frontend/notes/components/comment_form_spec.js +++ b/spec/frontend/notes/components/comment_form_spec.js @@ -9,7 +9,6 @@ import CommentForm from '~/notes/components/comment_form.vue'; import * as constants from '~/notes/constants'; import eventHub from '~/notes/event_hub'; import { refreshUserMergeRequestCounts } from '~/commons/nav/user_merge_requests'; -import UserAvatarLink from '~/vue_shared/components/user_avatar/user_avatar_link.vue'; import { loggedOutnoteableData, notesDataMock, userDataMock, noteableDataMock } from '../mock_data'; jest.mock('autosize'); @@ -64,14 +63,6 @@ describe('issue_comment_form component', () => { }); describe('user is logged in', () => { - describe('avatar', () => { - it('should render user avatar with link', () => { - mountComponent({ mountFunction: mount }); - - expect(wrapper.find(UserAvatarLink).attributes('href')).toBe(userDataMock.path); - }); - }); - describe('handleSave', () => { it('should request to save note when note is entered', () => { mountComponent({ mountFunction: mount, initialData: { note: 'hello world' } }); diff --git a/spec/frontend/notes/components/discussion_actions_spec.js b/spec/frontend/notes/components/discussion_actions_spec.js index 48e569720e9..03e5842bb0f 100644 --- a/spec/frontend/notes/components/discussion_actions_spec.js +++ b/spec/frontend/notes/components/discussion_actions_spec.js @@ -1,10 +1,10 @@ import { shallowMount, mount } from '@vue/test-utils'; -import { discussionMock } from '../mock_data'; 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 createStore from '~/notes/stores'; +import { discussionMock } from '../mock_data'; // NOTE: clone mock_data so that it is not accidentally mutated const createDiscussionMock = (props = {}) => diff --git a/spec/frontend/notes/components/discussion_counter_spec.js b/spec/frontend/notes/components/discussion_counter_spec.js index ebf7d52f38b..ca1972c9f61 100644 --- a/spec/frontend/notes/components/discussion_counter_spec.js +++ b/spec/frontend/notes/components/discussion_counter_spec.js @@ -3,8 +3,8 @@ import { shallowMount, createLocalVue } from '@vue/test-utils'; import { GlButton } from '@gitlab/ui'; import notesModule from '~/notes/stores/modules'; import DiscussionCounter from '~/notes/components/discussion_counter.vue'; -import { noteableDataMock, discussionMock, notesDataMock, userDataMock } from '../mock_data'; import * as types from '~/notes/stores/mutation_types'; +import { noteableDataMock, discussionMock, notesDataMock, userDataMock } from '../mock_data'; describe('DiscussionCounter component', () => { let store; diff --git a/spec/frontend/notes/components/note_actions_spec.js b/spec/frontend/notes/components/note_actions_spec.js index 3cfc1445cb8..7c3d747711c 100644 --- a/spec/frontend/notes/components/note_actions_spec.js +++ b/spec/frontend/notes/components/note_actions_spec.js @@ -1,11 +1,12 @@ import Vue from 'vue'; import { mount, createLocalVue, createWrapper } from '@vue/test-utils'; -import { TEST_HOST } from 'spec/test_constants'; import AxiosMockAdapter from 'axios-mock-adapter'; +import { TEST_HOST } from 'spec/test_constants'; import createStore from '~/notes/stores'; import noteActions from '~/notes/components/note_actions.vue'; -import { userDataMock } from '../mock_data'; import axios from '~/lib/utils/axios_utils'; +import { BV_HIDE_TOOLTIP } from '~/lib/utils/constants'; +import { userDataMock } from '../mock_data'; describe('noteActions', () => { let wrapper; @@ -135,7 +136,7 @@ describe('noteActions', () => { .then(() => { const emitted = Object.keys(rootWrapper.emitted()); - expect(emitted).toEqual(['bv::hide::tooltip']); + expect(emitted).toEqual([BV_HIDE_TOOLTIP]); done(); }) .catch(done.fail); diff --git a/spec/frontend/notes/components/note_form_spec.js b/spec/frontend/notes/components/note_form_spec.js index e64a75bede9..2ef99297540 100644 --- a/spec/frontend/notes/components/note_form_spec.js +++ b/spec/frontend/notes/components/note_form_spec.js @@ -4,9 +4,8 @@ import createStore from '~/notes/stores'; import NoteForm from '~/notes/components/note_form.vue'; import batchComments from '~/batch_comments/stores/modules/batch_comments'; import MarkdownField from '~/vue_shared/components/markdown/field.vue'; -import { noteableDataMock, notesDataMock, discussionMock } from '../mock_data'; - import { getDraft, updateDraft } from '~/lib/utils/autosave'; +import { noteableDataMock, notesDataMock, discussionMock } from '../mock_data'; jest.mock('~/lib/utils/autosave'); @@ -25,6 +24,8 @@ describe('issue_note_form component', () => { }); }; + const findCancelButton = () => wrapper.find('[data-testid="cancel"]'); + beforeEach(() => { getDraft.mockImplementation((key) => { if (key === dummyAutosaveKey) { @@ -160,8 +161,8 @@ describe('issue_note_form component', () => { }); await nextTick(); - const cancelButton = wrapper.find('[data-testid="cancel"]'); - cancelButton.trigger('click'); + const cancelButton = findCancelButton(); + cancelButton.vm.$emit('click'); await nextTick(); expect(wrapper.emitted().cancelForm).toHaveLength(1); @@ -177,7 +178,7 @@ describe('issue_note_form component', () => { const textarea = wrapper.find('textarea'); textarea.setValue('Foo'); const saveButton = wrapper.find('.js-vue-issue-save'); - saveButton.trigger('click'); + saveButton.vm.$emit('click'); expect(wrapper.vm.isSubmitting).toBe(true); }); @@ -272,7 +273,7 @@ describe('issue_note_form component', () => { await nextTick(); const cancelButton = wrapper.find('[data-testid="cancelBatchCommentsEnabled"]'); - cancelButton.trigger('click'); + cancelButton.vm.$emit('click'); expect(wrapper.vm.cancelHandler).toHaveBeenCalledWith(true); }); @@ -302,16 +303,16 @@ describe('issue_note_form component', () => { expect(wrapper.find('.js-resolve-checkbox').exists()).toBe(false); }); - it('hides actions for commits', () => { + it('hides actions for commits', async () => { wrapper.setProps({ discussion: { for_commit: true } }); - return nextTick(() => { - expect(wrapper.find('.note-form-actions').text()).not.toContain('Start a review'); - }); + await nextTick(); + + expect(wrapper.find('.note-form-actions').text()).not.toContain('Start a review'); }); describe('on enter', () => { - it('should start review or add to review when cmd+enter is pressed', () => { + it('should start review or add to review when cmd+enter is pressed', async () => { const textarea = wrapper.find('textarea'); jest.spyOn(wrapper.vm, 'handleAddToReview'); @@ -319,9 +320,8 @@ describe('issue_note_form component', () => { textarea.setValue('Foo'); textarea.trigger('keydown.enter', { metaKey: true }); - return nextTick(() => { - expect(wrapper.vm.handleAddToReview).toHaveBeenCalled(); - }); + await nextTick(); + expect(wrapper.vm.handleAddToReview).toHaveBeenCalled(); }); }); }); diff --git a/spec/frontend/notes/components/notes_app_spec.js b/spec/frontend/notes/components/notes_app_spec.js index e495a4738e0..45fbba2524a 100644 --- a/spec/frontend/notes/components/notes_app_spec.js +++ b/spec/frontend/notes/components/notes_app_spec.js @@ -10,9 +10,9 @@ import createStore from '~/notes/stores'; import * as constants from '~/notes/constants'; import '~/behaviors/markdown/render_gfm'; // TODO: use generated fixture (https://gitlab.com/gitlab-org/gitlab-foss/issues/62491) -import * as mockData from '../mock_data'; import * as urlUtility from '~/lib/utils/url_utility'; import OrderedLayout from '~/vue_shared/components/ordered_layout.vue'; +import * as mockData from '../mock_data'; jest.mock('~/user_popovers', () => jest.fn()); diff --git a/spec/frontend/notes/stores/actions_spec.js b/spec/frontend/notes/stores/actions_spec.js index f0e6a0a68dd..468e5af6f1a 100644 --- a/spec/frontend/notes/stores/actions_spec.js +++ b/spec/frontend/notes/stores/actions_spec.js @@ -1,5 +1,5 @@ -import { TEST_HOST } from 'spec/test_constants'; import AxiosMockAdapter from 'axios-mock-adapter'; +import { TEST_HOST } from 'spec/test_constants'; import testAction from 'helpers/vuex_action_helper'; import Api from '~/api'; import { deprecatedCreateFlash as Flash } from '~/flash'; @@ -9,7 +9,11 @@ import * as mutationTypes from '~/notes/stores/mutation_types'; import * as notesConstants from '~/notes/constants'; import createStore from '~/notes/stores'; import mrWidgetEventHub from '~/vue_merge_request_widget/event_hub'; -import { resetStore } from '../helpers'; +import axios from '~/lib/utils/axios_utils'; +import * as utils from '~/notes/stores/utils'; +import updateIssueConfidentialMutation from '~/sidebar/components/confidential/mutations/update_issue_confidential.mutation.graphql'; +import updateMergeRequestLockMutation from '~/sidebar/components/lock/mutations/update_merge_request_lock.mutation.graphql'; +import updateIssueLockMutation from '~/sidebar/components/lock/mutations/update_issue_lock.mutation.graphql'; import { discussionMock, notesDataMock, @@ -18,11 +22,7 @@ import { individualNote, batchSuggestionsInfoMock, } from '../mock_data'; -import axios from '~/lib/utils/axios_utils'; -import * as utils from '~/notes/stores/utils'; -import updateIssueConfidentialMutation from '~/sidebar/components/confidential/mutations/update_issue_confidential.mutation.graphql'; -import updateMergeRequestLockMutation from '~/sidebar/components/lock/mutations/update_merge_request_lock.mutation.graphql'; -import updateIssueLockMutation from '~/sidebar/components/lock/mutations/update_issue_lock.mutation.graphql'; +import { resetStore } from '../helpers'; const TEST_ERROR_MESSAGE = 'Test error message'; jest.mock('~/flash'); @@ -291,9 +291,45 @@ describe('Actions Notes Store', () => { [ { type: 'updateOrCreateNotes', payload: discussionMock.notes }, { type: 'startTaskList' }, + { type: 'updateResolvableDiscussionsCounts' }, ], )); }); + + describe('paginated notes feature flag enabled', () => { + const lastFetchedAt = '12358'; + + beforeEach(() => { + window.gon = { features: { paginatedNotes: true } }; + + axiosMock.onGet(notesDataMock.notesPath).replyOnce(200, { + notes: discussionMock.notes, + more: false, + last_fetched_at: lastFetchedAt, + }); + }); + + afterEach(() => { + window.gon = null; + }); + + it('should dispatch setFetchingState, setNotesFetchedState, setLoadingState, updateOrCreateNotes, startTaskList and commit SET_LAST_FETCHED_AT', () => { + return testAction( + actions.fetchData, + null, + { notesData: notesDataMock, isFetching: true }, + [{ type: 'SET_LAST_FETCHED_AT', payload: lastFetchedAt }], + [ + { type: 'setFetchingState', payload: false }, + { type: 'setNotesFetchedState', payload: true }, + { type: 'setLoadingState', payload: false }, + { type: 'updateOrCreateNotes', payload: discussionMock.notes }, + { type: 'startTaskList' }, + { type: 'updateResolvableDiscussionsCounts' }, + ], + ); + }); + }); }); describe('poll', () => { @@ -1355,4 +1391,17 @@ describe('Actions Notes Store', () => { ); }); }); + + describe('setFetchingState', () => { + it('commits SET_NOTES_FETCHING_STATE', (done) => { + testAction( + actions.setFetchingState, + true, + null, + [{ type: mutationTypes.SET_NOTES_FETCHING_STATE, payload: true }], + [], + done, + ); + }); + }); }); diff --git a/spec/frontend/notes/stores/mutation_spec.js b/spec/frontend/notes/stores/mutation_spec.js index 66fc74525ad..c4301f63470 100644 --- a/spec/frontend/notes/stores/mutation_spec.js +++ b/spec/frontend/notes/stores/mutation_spec.js @@ -400,6 +400,19 @@ describe('Notes Store mutations', () => { expect(state.discussions[0].notes[0].note).toEqual('Foo'); }); + it('does not update existing note if it matches', () => { + const state = { + discussions: [{ ...individualNote, individual_note: false }], + }; + jest.spyOn(state.discussions[0].notes, 'splice'); + + const updated = individualNote.notes[0]; + + mutations.UPDATE_NOTE(state, updated); + + expect(state.discussions[0].notes.splice).not.toHaveBeenCalled(); + }); + it('transforms an individual note to discussion', () => { const state = { discussions: [individualNote], |