diff options
author | Fatih Acet <acetfatih@gmail.com> | 2019-01-28 22:44:17 +0000 |
---|---|---|
committer | Fatih Acet <acetfatih@gmail.com> | 2019-01-28 22:44:17 +0000 |
commit | f6c8e9c604a9966980e78c1c56d6e28e69ebbdff (patch) | |
tree | d73c706a4a4a7a916de457dcc7d727b95f2e8d98 | |
parent | bbf6e65dd2874ae1866ee6d87713f45de1f95d55 (diff) | |
parent | 56c62208f6be6392ad428d0be40befc918de8c67 (diff) | |
download | gitlab-ce-f6c8e9c604a9966980e78c1c56d6e28e69ebbdff.tar.gz |
Merge branch 'refactor/56366-extract-resolve-discussion-button' into 'master'
refactor(NoteableDiscussion): Extracted ResolveDiscussionButton from
See merge request gitlab-org/gitlab-ce!24505
4 files changed, 115 insertions, 10 deletions
diff --git a/app/assets/javascripts/notes/components/discussion_resolve_button.vue b/app/assets/javascripts/notes/components/discussion_resolve_button.vue new file mode 100644 index 00000000000..2b29d710236 --- /dev/null +++ b/app/assets/javascripts/notes/components/discussion_resolve_button.vue @@ -0,0 +1,28 @@ +<script> +export default { + name: 'ResolveDiscussionButton', + props: { + isResolving: { + type: Boolean, + required: false, + default: false, + }, + buttonTitle: { + type: String, + required: true, + }, + }, +}; +</script> + +<template> + <button ref="button" type="button" class="btn btn-default ml-sm-2" @click="$emit('onClick')"> + <i + v-if="isResolving" + ref="isResolvingIcon" + aria-hidden="true" + class="fa fa-spinner fa-spin" + ></i> + {{ buttonTitle }} + </button> +</template> diff --git a/app/assets/javascripts/notes/components/noteable_discussion.vue b/app/assets/javascripts/notes/components/noteable_discussion.vue index 8add7278f9b..695efe3602f 100644 --- a/app/assets/javascripts/notes/components/noteable_discussion.vue +++ b/app/assets/javascripts/notes/components/noteable_discussion.vue @@ -12,6 +12,7 @@ import { SYSTEM_NOTE } from '../constants'; import userAvatarLink from '../../vue_shared/components/user_avatar/user_avatar_link.vue'; import noteableNote from './noteable_note.vue'; import noteHeader from './note_header.vue'; +import resolveDiscussionButton from './discussion_resolve_button.vue'; import toggleRepliesWidget from './toggle_replies_widget.vue'; import noteSignedOutWidget from './note_signed_out_widget.vue'; import noteEditedText from './note_edited_text.vue'; @@ -35,6 +36,7 @@ export default { noteSignedOutWidget, noteEditedText, noteForm, + resolveDiscussionButton, jumpToNextDiscussionButton, toggleRepliesWidget, placeholderNote, @@ -453,16 +455,12 @@ Please check your network connection and try again.`; > Reply... </button> - <div v-if="discussion.resolvable"> - <button - type="button" - class="btn btn-default ml-sm-2" - @click="resolveHandler()" - > - <i v-if="isResolving" aria-hidden="true" class="fa fa-spinner fa-spin"></i> - {{ resolveButtonTitle }} - </button> - </div> + <resolve-discussion-button + v-if="discussion.resolvable" + :is-resolving="isResolving" + :button-title="resolveButtonTitle" + @onClick="resolveHandler" + /> <div v-if="discussion.resolvable" class="btn-group discussion-actions ml-sm-2" diff --git a/changelogs/unreleased/refactor-56366-extract-resolve-discussion-button.yml b/changelogs/unreleased/refactor-56366-extract-resolve-discussion-button.yml new file mode 100644 index 00000000000..98859e8aa07 --- /dev/null +++ b/changelogs/unreleased/refactor-56366-extract-resolve-discussion-button.yml @@ -0,0 +1,5 @@ +--- +title: Refactored NoteableDiscussion by extracting ResolveDiscussionButton +merge_request: 24505 +author: Martin Hobert +type: other diff --git a/spec/javascripts/notes/components/discussion_resolve_button_spec.js b/spec/javascripts/notes/components/discussion_resolve_button_spec.js new file mode 100644 index 00000000000..5024f40ec5d --- /dev/null +++ b/spec/javascripts/notes/components/discussion_resolve_button_spec.js @@ -0,0 +1,74 @@ +import resolveDiscussionButton from '~/notes/components/discussion_resolve_button.vue'; +import { createLocalVue, shallowMount } from '@vue/test-utils'; + +const buttonTitle = 'Resolve discussion'; + +describe('resolveDiscussionButton', () => { + let wrapper; + let localVue; + + const factory = options => { + localVue = createLocalVue(); + wrapper = shallowMount(resolveDiscussionButton, { + localVue, + ...options, + }); + }; + + beforeEach(() => { + factory({ + propsData: { + isResolving: false, + buttonTitle, + }, + }); + }); + + afterEach(() => { + wrapper.destroy(); + }); + + it('should emit a onClick event on button click', () => { + const button = wrapper.find({ ref: 'button' }); + + button.trigger('click'); + + expect(wrapper.emitted()).toEqual({ + onClick: [[]], + }); + }); + + it('should contain the provided button title', () => { + const button = wrapper.find({ ref: 'button' }); + + expect(button.text()).toContain(buttonTitle); + }); + + it('should show a loading spinner while resolving', () => { + factory({ + propsData: { + isResolving: true, + buttonTitle, + }, + }); + + const button = wrapper.find({ ref: 'isResolvingIcon' }); + + expect(button.exists()).toEqual(true); + }); + + it('should only show a loading spinner while resolving', () => { + factory({ + propsData: { + isResolving: false, + buttonTitle, + }, + }); + + const button = wrapper.find({ ref: 'isResolvingIcon' }); + + localVue.nextTick(() => { + expect(button.exists()).toEqual(false); + }); + }); +}); |