diff options
Diffstat (limited to 'spec/frontend/notes/components/noteable_discussion_spec.js')
-rw-r--r-- | spec/frontend/notes/components/noteable_discussion_spec.js | 187 |
1 files changed, 187 insertions, 0 deletions
diff --git a/spec/frontend/notes/components/noteable_discussion_spec.js b/spec/frontend/notes/components/noteable_discussion_spec.js new file mode 100644 index 00000000000..b91f599f158 --- /dev/null +++ b/spec/frontend/notes/components/noteable_discussion_spec.js @@ -0,0 +1,187 @@ +import { mount, createLocalVue } from '@vue/test-utils'; +import createStore from '~/notes/stores'; +import noteableDiscussion from '~/notes/components/noteable_discussion.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'; +import '~/behaviors/markdown/render_gfm'; +import { + noteableDataMock, + discussionMock, + notesDataMock, + loggedOutnoteableData, + userDataMock, +} from '../mock_data'; +import mockDiffFile from 'jest/diffs/mock_data/diff_file'; +import { trimText } from 'helpers/text_helper'; + +const discussionWithTwoUnresolvedNotes = 'merge_requests/resolved_diff_discussion.json'; + +const localVue = createLocalVue(); + +describe('noteable_discussion component', () => { + let store; + let wrapper; + let originalGon; + + preloadFixtures(discussionWithTwoUnresolvedNotes); + + beforeEach(() => { + window.mrTabs = {}; + store = createStore(); + store.dispatch('setNoteableData', noteableDataMock); + store.dispatch('setNotesData', notesDataMock); + + wrapper = mount(localVue.extend(noteableDiscussion), { + store, + propsData: { discussion: discussionMock }, + localVue, + }); + }); + + afterEach(() => { + wrapper.destroy(); + }); + + it('should not render thread header for non diff threads', () => { + expect(wrapper.find('.discussion-header').exists()).toBe(false); + }); + + it('should render thread header', () => { + const discussion = { ...discussionMock }; + discussion.diff_file = mockDiffFile; + discussion.diff_discussion = true; + discussion.expanded = false; + + wrapper.setProps({ discussion }); + + return wrapper.vm.$nextTick().then(() => { + expect(wrapper.find('.discussion-header').exists()).toBe(true); + }); + }); + + describe('actions', () => { + it('should toggle reply form', () => { + const replyPlaceholder = wrapper.find(ReplyPlaceholder); + + return wrapper.vm + .$nextTick() + .then(() => { + expect(wrapper.vm.isReplying).toEqual(false); + + replyPlaceholder.vm.$emit('onClick'); + }) + .then(() => wrapper.vm.$nextTick()) + .then(() => { + expect(wrapper.vm.isReplying).toEqual(true); + + const noteForm = wrapper.find(NoteForm); + + expect(noteForm.exists()).toBe(true); + + 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('does not render jump to thread button', () => { + expect(wrapper.find('*[data-original-title="Jump to next unresolved thread"]').exists()).toBe( + false, + ); + }); + }); + + describe('for resolved thread', () => { + beforeEach(() => { + const discussion = getJSONFixture(discussionWithTwoUnresolvedNotes)[0]; + wrapper.setProps({ discussion }); + }); + + it('does not display a button to resolve with issue', () => { + const button = wrapper.find(ResolveWithIssueButton); + + expect(button.exists()).toBe(false); + }); + }); + + describe('for unresolved thread', () => { + beforeEach(() => { + const discussion = { + ...getJSONFixture(discussionWithTwoUnresolvedNotes)[0], + expanded: true, + }; + discussion.notes = discussion.notes.map(note => ({ + ...note, + resolved: false, + current_user: { + ...note.current_user, + can_resolve: true, + }, + })); + + wrapper.setProps({ discussion }); + + return wrapper.vm.$nextTick(); + }); + + it('displays a button to resolve with issue', () => { + const button = wrapper.find(ResolveWithIssueButton); + + expect(button.exists()).toBe(true); + }); + }); + + describe('signout widget', () => { + beforeEach(() => { + originalGon = Object.assign({}, window.gon); + window.gon = window.gon || {}; + }); + + afterEach(() => { + wrapper.destroy(); + window.gon = originalGon; + }); + + describe('user is logged in', () => { + beforeEach(() => { + window.gon.current_user_id = userDataMock.id; + store.dispatch('setUserData', userDataMock); + + wrapper = mount(localVue.extend(noteableDiscussion), { + store, + propsData: { discussion: discussionMock }, + localVue, + }); + }); + + it('should not render signed out widget', () => { + expect(Boolean(wrapper.vm.isLoggedIn)).toBe(true); + expect(trimText(wrapper.text())).not.toContain('Please register or sign in to reply'); + }); + }); + + describe('user is not logged in', () => { + beforeEach(() => { + window.gon.current_user_id = null; + store.dispatch('setNoteableData', loggedOutnoteableData); + store.dispatch('setNotesData', notesDataMock); + + wrapper = mount(localVue.extend(noteableDiscussion), { + store, + propsData: { discussion: discussionMock }, + localVue, + }); + }); + + it('should render signed out widget', () => { + expect(Boolean(wrapper.vm.isLoggedIn)).toBe(false); + expect(trimText(wrapper.text())).toContain('Please register or sign in to reply'); + }); + }); + }); +}); |