diff --git a/app/assets/javascripts/stars/components/star_count.vue b/app/assets/javascripts/stars/components/star_count.vue index d3a44152d3e465bb633d47202eb7537a73fb9a14..332d58d39282eb7f42dbb4825b068ebe1ac89fcb 100644 --- a/app/assets/javascripts/stars/components/star_count.vue +++ b/app/assets/javascripts/stars/components/star_count.vue @@ -36,6 +36,7 @@ export default { }, data() { return { + isLoading: false, count: this.starCount, isStarred: this.starred, }; @@ -52,7 +53,7 @@ export default { }, tooltip() { if (isLoggedIn()) { - return this.starText; + return ''; } return s__('ProjectOverview|You must sign in to star a project'); @@ -75,6 +76,7 @@ export default { } try { + this.isLoading = true; const { data } = await this.$apollo.mutate({ mutation: setStarStatusMutation, variables: { @@ -93,6 +95,8 @@ export default { } catch (failure) { reportToSentry(this.$options.name, failure); this.showToastMessage(); + } finally { + this.isLoading = false; } }, }, @@ -109,6 +113,7 @@ export default { data-testid="star-button" :title="tooltip" :href="starHref" + :disabled="isLoading" @click="setStarStatus()" > diff --git a/spec/frontend/stars/components/star_count_spec.js b/spec/frontend/stars/components/star_count_spec.js index b07ae1d9e2928873b77d7d882c475c3e81e56d17..27feb04cda2e1c15236e9ea35e05e34915806369 100644 --- a/spec/frontend/stars/components/star_count_spec.js +++ b/spec/frontend/stars/components/star_count_spec.js @@ -1,5 +1,5 @@ import VueApollo from 'vue-apollo'; -import Vue from 'vue'; +import Vue, { nextTick } from 'vue'; import { mountExtended } from 'helpers/vue_test_utils_helper'; import StarCount from '~/stars/components/star_count.vue'; import createMockApollo from 'helpers/mock_apollo_helper'; @@ -151,4 +151,32 @@ describe('StarCount', () => { expect(findStarButton().attributes('href')).toBe('sign/in/path'); }); }); + + describe('star button state', () => { + it('is disabled when query is running and enabled when query is succesful', async () => { + createComponent(); + const starButton = findStarButton(); + + starButton.vm.$emit('click'); + await nextTick(); + expect(starButton.props('disabled')).toBe(true); + + await waitForPromises(); + expect(starButton.props('disabled')).toBe(false); + }); + + it('is disabled when query is running and enabled when query fails', async () => { + createComponent({ + setStarStatusHandler: jest.fn().mockRejectedValue('Internal server error'), + }); + const starButton = findStarButton(); + + starButton.vm.$emit('click'); + await nextTick(); + expect(starButton.props('disabled')).toBe(true); + + await waitForPromises(); + expect(starButton.props('disabled')).toBe(false); + }); + }); });