Commit 1d50c904 authored by Tom Quirk's avatar Tom Quirk

Move integration reset code from Vuex to component

Reset logic is only used by the integration form component.
This commit removes reset logic from the Vuex state, and
adds it to the integration_form.vue component.

Tests have been updated. There should be no
user-facing changes.
parent 2d124bc4
<script> <script>
import { GlButton, GlModalDirective, GlSafeHtmlDirective as SafeHtml } from '@gitlab/ui'; import { GlButton, GlModalDirective, GlSafeHtmlDirective as SafeHtml } from '@gitlab/ui';
import axios from 'axios';
import * as Sentry from '@sentry/browser'; import * as Sentry from '@sentry/browser';
import { mapState, mapActions, mapGetters } from 'vuex'; import { mapState, mapActions, mapGetters } from 'vuex';
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
...@@ -10,6 +11,7 @@ import { ...@@ -10,6 +11,7 @@ import {
I18N_SUCCESSFUL_CONNECTION_MESSAGE, I18N_SUCCESSFUL_CONNECTION_MESSAGE,
integrationLevels, integrationLevels,
} from '~/integrations/constants'; } from '~/integrations/constants';
import { refreshCurrentPage } from '~/lib/utils/url_utility';
import eventHub from '../event_hub'; import eventHub from '../event_hub';
import { testIntegrationSettings } from '../api'; import { testIntegrationSettings } from '../api';
import ActiveCheckbox from './active_checkbox.vue'; import ActiveCheckbox from './active_checkbox.vue';
...@@ -55,11 +57,12 @@ export default { ...@@ -55,11 +57,12 @@ export default {
integrationActive: false, integrationActive: false,
isTesting: false, isTesting: false,
isSaving: false, isSaving: false,
isResetting: false,
}; };
}, },
computed: { computed: {
...mapGetters(['currentKey', 'propsSource']), ...mapGetters(['currentKey', 'propsSource']),
...mapState(['defaultState', 'customState', 'override', 'isResetting']), ...mapState(['defaultState', 'customState', 'override']),
isEditable() { isEditable() {
return this.propsSource.editable; return this.propsSource.editable;
}, },
...@@ -126,7 +129,20 @@ export default { ...@@ -126,7 +129,20 @@ export default {
}); });
}, },
onResetClick() { onResetClick() {
this.fetchResetIntegration(); this.isResetting = true;
return axios
.post(this.propsSource.resetPath)
.then(() => {
refreshCurrentPage();
})
.catch((error) => {
this.$toast.show(I18N_DEFAULT_ERROR_MESSAGE);
Sentry.captureException(error);
})
.finally(() => {
this.isResetting = false;
});
}, },
onRequestJiraIssueTypes() { onRequestJiraIssueTypes() {
this.requestJiraIssueTypes(this.getFormData()); this.requestJiraIssueTypes(this.getFormData());
...@@ -208,6 +224,7 @@ export default { ...@@ -208,6 +224,7 @@ export default {
variant="confirm" variant="confirm"
:loading="isSaving" :loading="isSaving"
:disabled="disableButtons" :disabled="disableButtons"
data-testid="save-button-instance-group"
data-qa-selector="save_changes_button" data-qa-selector="save_changes_button"
> >
{{ __('Save changes') }} {{ __('Save changes') }}
......
...@@ -11,7 +11,7 @@ export default { ...@@ -11,7 +11,7 @@ export default {
primaryProps() { primaryProps() {
return { return {
text: __('Reset'), text: __('Reset'),
attributes: [{ variant: 'warning' }, { category: 'primary' }], attributes: [{ variant: 'danger' }, { category: 'primary' }],
}; };
}, },
cancelProps() { cancelProps() {
......
import axios from 'axios';
import { refreshCurrentPage } from '~/lib/utils/url_utility';
import { import {
VALIDATE_INTEGRATION_FORM_EVENT, VALIDATE_INTEGRATION_FORM_EVENT,
I18N_FETCH_TEST_SETTINGS_DEFAULT_ERROR_MESSAGE, I18N_FETCH_TEST_SETTINGS_DEFAULT_ERROR_MESSAGE,
...@@ -10,27 +8,6 @@ import eventHub from '../event_hub'; ...@@ -10,27 +8,6 @@ import eventHub from '../event_hub';
import * as types from './mutation_types'; import * as types from './mutation_types';
export const setOverride = ({ commit }, override) => commit(types.SET_OVERRIDE, override); export const setOverride = ({ commit }, override) => commit(types.SET_OVERRIDE, override);
export const setIsResetting = ({ commit }, isResetting) =>
commit(types.SET_IS_RESETTING, isResetting);
export const requestResetIntegration = ({ commit }) => {
commit(types.REQUEST_RESET_INTEGRATION);
};
export const receiveResetIntegrationSuccess = () => {
refreshCurrentPage();
};
export const receiveResetIntegrationError = ({ commit }) => {
commit(types.RECEIVE_RESET_INTEGRATION_ERROR);
};
export const fetchResetIntegration = ({ dispatch, getters }) => {
dispatch('requestResetIntegration');
return axios
.post(getters.propsSource.resetPath, { params: { format: 'json' } })
.then(() => dispatch('receiveResetIntegrationSuccess'))
.catch(() => dispatch('receiveResetIntegrationError'));
};
export const requestJiraIssueTypes = ({ commit, dispatch, getters }, formData) => { export const requestJiraIssueTypes = ({ commit, dispatch, getters }, formData) => {
commit(types.SET_JIRA_ISSUE_TYPES_ERROR_MESSAGE, ''); commit(types.SET_JIRA_ISSUE_TYPES_ERROR_MESSAGE, '');
......
...@@ -4,15 +4,6 @@ export default { ...@@ -4,15 +4,6 @@ export default {
[types.SET_OVERRIDE](state, override) { [types.SET_OVERRIDE](state, override) {
state.override = override; state.override = override;
}, },
[types.SET_IS_RESETTING](state, isResetting) {
state.isResetting = isResetting;
},
[types.REQUEST_RESET_INTEGRATION](state) {
state.isResetting = true;
},
[types.RECEIVE_RESET_INTEGRATION_ERROR](state) {
state.isResetting = false;
},
[types.SET_JIRA_ISSUE_TYPES](state, jiraIssueTypes) { [types.SET_JIRA_ISSUE_TYPES](state, jiraIssueTypes) {
state.jiraIssueTypes = jiraIssueTypes; state.jiraIssueTypes = jiraIssueTypes;
}, },
......
...@@ -5,8 +5,6 @@ export default ({ defaultState = null, customState = {} } = {}) => { ...@@ -5,8 +5,6 @@ export default ({ defaultState = null, customState = {} } = {}) => {
override, override,
defaultState, defaultState,
customState, customState,
isSaving: false,
isResetting: false,
isLoadingJiraIssueTypes: false, isLoadingJiraIssueTypes: false,
loadingJiraIssueTypesErrorMessage: '', loadingJiraIssueTypesErrorMessage: '',
jiraIssueTypes: [], jiraIssueTypes: [],
......
...@@ -3,7 +3,7 @@ import MockAdapter from 'axios-mock-adapter'; ...@@ -3,7 +3,7 @@ import MockAdapter from 'axios-mock-adapter';
import * as Sentry from '@sentry/browser'; import * as Sentry from '@sentry/browser';
import { setHTMLFixture } from 'helpers/fixtures'; import { setHTMLFixture } from 'helpers/fixtures';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper'; import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import { mockIntegrationProps } from 'jest/integrations/edit/mock_data'; import waitForPromises from 'helpers/wait_for_promises';
import ActiveCheckbox from '~/integrations/edit/components/active_checkbox.vue'; import ActiveCheckbox from '~/integrations/edit/components/active_checkbox.vue';
import ConfirmationModal from '~/integrations/edit/components/confirmation_modal.vue'; import ConfirmationModal from '~/integrations/edit/components/confirmation_modal.vue';
import DynamicField from '~/integrations/edit/components/dynamic_field.vue'; import DynamicField from '~/integrations/edit/components/dynamic_field.vue';
...@@ -13,7 +13,6 @@ import JiraTriggerFields from '~/integrations/edit/components/jira_trigger_field ...@@ -13,7 +13,6 @@ import JiraTriggerFields from '~/integrations/edit/components/jira_trigger_field
import OverrideDropdown from '~/integrations/edit/components/override_dropdown.vue'; import OverrideDropdown from '~/integrations/edit/components/override_dropdown.vue';
import ResetConfirmationModal from '~/integrations/edit/components/reset_confirmation_modal.vue'; import ResetConfirmationModal from '~/integrations/edit/components/reset_confirmation_modal.vue';
import TriggerFields from '~/integrations/edit/components/trigger_fields.vue'; import TriggerFields from '~/integrations/edit/components/trigger_fields.vue';
import waitForPromises from 'helpers/wait_for_promises';
import { import {
integrationLevels, integrationLevels,
I18N_SUCCESSFUL_CONNECTION_MESSAGE, I18N_SUCCESSFUL_CONNECTION_MESSAGE,
...@@ -23,9 +22,12 @@ import { ...@@ -23,9 +22,12 @@ import {
import { createStore } from '~/integrations/edit/store'; import { createStore } from '~/integrations/edit/store';
import eventHub from '~/integrations/edit/event_hub'; import eventHub from '~/integrations/edit/event_hub';
import httpStatus from '~/lib/utils/http_status'; import httpStatus from '~/lib/utils/http_status';
import { refreshCurrentPage } from '~/lib/utils/url_utility';
import { mockIntegrationProps } from '../mock_data';
jest.mock('~/integrations/edit/event_hub'); jest.mock('~/integrations/edit/event_hub');
jest.mock('@sentry/browser'); jest.mock('@sentry/browser');
jest.mock('~/lib/utils/url_utility');
describe('IntegrationForm', () => { describe('IntegrationForm', () => {
const mockToastShow = jest.fn(); const mockToastShow = jest.fn();
...@@ -80,7 +82,8 @@ describe('IntegrationForm', () => { ...@@ -80,7 +82,8 @@ describe('IntegrationForm', () => {
const findConfirmationModal = () => wrapper.findComponent(ConfirmationModal); const findConfirmationModal = () => wrapper.findComponent(ConfirmationModal);
const findResetConfirmationModal = () => wrapper.findComponent(ResetConfirmationModal); const findResetConfirmationModal = () => wrapper.findComponent(ResetConfirmationModal);
const findResetButton = () => wrapper.findByTestId('reset-button'); const findResetButton = () => wrapper.findByTestId('reset-button');
const findSaveButton = () => wrapper.findByTestId('save-button'); const findProjectSaveButton = () => wrapper.findByTestId('save-button');
const findInstanceOrGroupSaveButton = () => wrapper.findByTestId('save-button-instance-group');
const findTestButton = () => wrapper.findByTestId('test-button'); const findTestButton = () => wrapper.findByTestId('test-button');
const findJiraTriggerFields = () => wrapper.findComponent(JiraTriggerFields); const findJiraTriggerFields = () => wrapper.findComponent(JiraTriggerFields);
const findJiraIssuesFields = () => wrapper.findComponent(JiraIssuesFields); const findJiraIssuesFields = () => wrapper.findComponent(JiraIssuesFields);
...@@ -395,11 +398,11 @@ describe('IntegrationForm', () => { ...@@ -395,11 +398,11 @@ describe('IntegrationForm', () => {
}, },
}); });
await findSaveButton().vm.$emit('click', new Event('click')); await findProjectSaveButton().vm.$emit('click', new Event('click'));
}); });
it('sets save button `loading` prop to `true`', () => { it('sets save button `loading` prop to `true`', () => {
expect(findSaveButton().props('loading')).toBe(true); expect(findProjectSaveButton().props('loading')).toBe(true);
}); });
it('sets test button `disabled` prop to `true`', () => { it('sets test button `disabled` prop to `true`', () => {
...@@ -425,7 +428,7 @@ describe('IntegrationForm', () => { ...@@ -425,7 +428,7 @@ describe('IntegrationForm', () => {
}, },
}); });
await findSaveButton().vm.$emit('click', new Event('click')); await findProjectSaveButton().vm.$emit('click', new Event('click'));
}); });
it('submit form', () => { it('submit form', () => {
...@@ -445,7 +448,7 @@ describe('IntegrationForm', () => { ...@@ -445,7 +448,7 @@ describe('IntegrationForm', () => {
}, },
}); });
await findSaveButton().vm.$emit('click', new Event('click')); await findProjectSaveButton().vm.$emit('click', new Event('click'));
}); });
it('does not submit form', () => { it('does not submit form', () => {
...@@ -453,7 +456,7 @@ describe('IntegrationForm', () => { ...@@ -453,7 +456,7 @@ describe('IntegrationForm', () => {
}); });
it('sets save button `loading` prop to `false`', () => { it('sets save button `loading` prop to `false`', () => {
expect(findSaveButton().props('loading')).toBe(false); expect(findProjectSaveButton().props('loading')).toBe(false);
}); });
it('sets test button `disabled` prop to `false`', () => { it('sets test button `disabled` prop to `false`', () => {
...@@ -507,7 +510,7 @@ describe('IntegrationForm', () => { ...@@ -507,7 +510,7 @@ describe('IntegrationForm', () => {
}); });
it('sets save button `disabled` prop to `true`', () => { it('sets save button `disabled` prop to `true`', () => {
expect(findSaveButton().props('disabled')).toBe(true); expect(findProjectSaveButton().props('disabled')).toBe(true);
}); });
}); });
...@@ -536,7 +539,7 @@ describe('IntegrationForm', () => { ...@@ -536,7 +539,7 @@ describe('IntegrationForm', () => {
}); });
it('sets save button `disabled` prop to `false`', () => { it('sets save button `disabled` prop to `false`', () => {
expect(findSaveButton().props('disabled')).toBe(false); expect(findProjectSaveButton().props('disabled')).toBe(false);
}); });
it(`${expectSentry ? 'does' : 'does not'} capture exception in Sentry`, () => { it(`${expectSentry ? 'does' : 'does not'} capture exception in Sentry`, () => {
...@@ -545,4 +548,83 @@ describe('IntegrationForm', () => { ...@@ -545,4 +548,83 @@ describe('IntegrationForm', () => {
}); });
}); });
}); });
describe('when `reset-confirmation-modal` emits `reset` event', () => {
const mockResetPath = '/reset';
describe('buttons', () => {
beforeEach(async () => {
createComponent({
customStateProps: {
integrationLevel: integrationLevels.GROUP,
canTest: true,
resetPath: mockResetPath,
},
});
await findResetConfirmationModal().vm.$emit('reset');
});
it('sets reset button `loading` prop to `true`', () => {
expect(findResetButton().props('loading')).toBe(true);
});
it('sets other button `disabled` props to `true`', () => {
expect(findInstanceOrGroupSaveButton().props('disabled')).toBe(true);
expect(findTestButton().props('disabled')).toBe(true);
});
});
describe('when "reset settings" request fails', () => {
beforeEach(async () => {
mockAxios.onPost(mockResetPath).replyOnce(httpStatus.INTERNAL_SERVER_ERROR);
createComponent({
customStateProps: {
integrationLevel: integrationLevels.GROUP,
canTest: true,
resetPath: mockResetPath,
},
});
await findResetConfirmationModal().vm.$emit('reset');
await waitForPromises();
});
it('displays a toast', () => {
expect(mockToastShow).toHaveBeenCalledWith(I18N_DEFAULT_ERROR_MESSAGE);
});
it('captures exception in Sentry', () => {
expect(Sentry.captureException).toHaveBeenCalledTimes(1);
});
it('sets reset button `loading` prop to `false`', () => {
expect(findResetButton().props('loading')).toBe(false);
});
it('sets button `disabled` props to `false`', () => {
expect(findInstanceOrGroupSaveButton().props('disabled')).toBe(false);
expect(findTestButton().props('disabled')).toBe(false);
});
});
describe('when "reset settings" succeeds', () => {
beforeEach(async () => {
mockAxios.onPost(mockResetPath).replyOnce(httpStatus.OK);
createComponent({
customStateProps: {
integrationLevel: integrationLevels.GROUP,
resetPath: mockResetPath,
},
});
await findResetConfirmationModal().vm.$emit('reset');
await waitForPromises();
});
it('calls `refreshCurrentPage`', () => {
expect(refreshCurrentPage).toHaveBeenCalledTimes(1);
});
});
});
}); });
...@@ -4,17 +4,12 @@ import testAction from 'helpers/vuex_action_helper'; ...@@ -4,17 +4,12 @@ import testAction from 'helpers/vuex_action_helper';
import { I18N_FETCH_TEST_SETTINGS_DEFAULT_ERROR_MESSAGE } from '~/integrations/constants'; import { I18N_FETCH_TEST_SETTINGS_DEFAULT_ERROR_MESSAGE } from '~/integrations/constants';
import { import {
setOverride, setOverride,
setIsResetting,
requestResetIntegration,
receiveResetIntegrationSuccess,
receiveResetIntegrationError,
requestJiraIssueTypes, requestJiraIssueTypes,
receiveJiraIssueTypesSuccess, receiveJiraIssueTypesSuccess,
receiveJiraIssueTypesError, receiveJiraIssueTypesError,
} from '~/integrations/edit/store/actions'; } from '~/integrations/edit/store/actions';
import * as types from '~/integrations/edit/store/mutation_types'; import * as types from '~/integrations/edit/store/mutation_types';
import createState from '~/integrations/edit/store/state'; import createState from '~/integrations/edit/store/state';
import { refreshCurrentPage } from '~/lib/utils/url_utility';
import { mockJiraIssueTypes } from '../mock_data'; import { mockJiraIssueTypes } from '../mock_data';
jest.mock('~/lib/utils/url_utility'); jest.mock('~/lib/utils/url_utility');
...@@ -38,38 +33,6 @@ describe('Integration form store actions', () => { ...@@ -38,38 +33,6 @@ describe('Integration form store actions', () => {
}); });
}); });
describe('setIsResetting', () => {
it('should commit isResetting mutation', () => {
return testAction(setIsResetting, true, state, [
{ type: types.SET_IS_RESETTING, payload: true },
]);
});
});
describe('requestResetIntegration', () => {
it('should commit REQUEST_RESET_INTEGRATION mutation', () => {
return testAction(requestResetIntegration, null, state, [
{ type: types.REQUEST_RESET_INTEGRATION },
]);
});
});
describe('receiveResetIntegrationSuccess', () => {
it('should call refreshCurrentPage()', () => {
return testAction(receiveResetIntegrationSuccess, null, state, [], [], () => {
expect(refreshCurrentPage).toHaveBeenCalled();
});
});
});
describe('receiveResetIntegrationError', () => {
it('should commit RECEIVE_RESET_INTEGRATION_ERROR mutation', () => {
return testAction(receiveResetIntegrationError, null, state, [
{ type: types.RECEIVE_RESET_INTEGRATION_ERROR },
]);
});
});
describe('requestJiraIssueTypes', () => { describe('requestJiraIssueTypes', () => {
describe.each` describe.each`
scenario | responseCode | response | action scenario | responseCode | response | action
......
...@@ -17,30 +17,6 @@ describe('Integration form store mutations', () => { ...@@ -17,30 +17,6 @@ describe('Integration form store mutations', () => {
}); });
}); });
describe(`${types.SET_IS_RESETTING}`, () => {
it('sets isResetting', () => {
mutations[types.SET_IS_RESETTING](state, true);
expect(state.isResetting).toBe(true);
});
});
describe(`${types.REQUEST_RESET_INTEGRATION}`, () => {
it('sets isResetting', () => {
mutations[types.REQUEST_RESET_INTEGRATION](state);
expect(state.isResetting).toBe(true);
});
});
describe(`${types.RECEIVE_RESET_INTEGRATION_ERROR}`, () => {
it('sets isResetting', () => {
mutations[types.RECEIVE_RESET_INTEGRATION_ERROR](state);
expect(state.isResetting).toBe(false);
});
});
describe(`${types.SET_JIRA_ISSUE_TYPES}`, () => { describe(`${types.SET_JIRA_ISSUE_TYPES}`, () => {
it('sets jiraIssueTypes', () => { it('sets jiraIssueTypes', () => {
const jiraIssueTypes = ['issue', 'epic']; const jiraIssueTypes = ['issue', 'epic'];
......
...@@ -5,8 +5,6 @@ describe('Integration form state factory', () => { ...@@ -5,8 +5,6 @@ describe('Integration form state factory', () => {
expect(createState()).toEqual({ expect(createState()).toEqual({
defaultState: null, defaultState: null,
customState: {}, customState: {},
isSaving: false,
isResetting: false,
override: false, override: false,
isLoadingJiraIssueTypes: false, isLoadingJiraIssueTypes: false,
jiraIssueTypes: [], jiraIssueTypes: [],
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment